A postcript viewer. It decodes a .ps - Postscript
This program takes the input of a Postcript file, converts the codes in it to plain text which is displayed and re-directable. http://www.cs.latrobe.edu.au/~yuand/ansi_c/index.html
AI
Riepilogo AI: This codebase represents a historical implementation of the logic described in the metadata. Our preservation engine analyzes the structure to provide context for modern developers.
Codice sorgente
/*********************************************************************/
/* */
/* Title: dpview.c */
/* */
/* Comments: This program takes the input of a Postcript file, */
/* converts the codes in it to plain text which is */
/* displayed and re-directable. */
/* */
/* Author: David Yuan */
/* */
/* Date Created: 19/04/1996 */
/* */
/* Date Last Modified: 16/06/1996 */
/* */
/* Permission of distribution is granted, provided no alternation, */
/* commenting or modification is made towards any parts of */
/* the source code and the binary code. */
/* */
/*********************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "file_handle.c"
#include "fggets.c"
#define INDICATOR_STR1 "%%EndSetup" /* First string to be searched */
#define INDICATOR_STR2 "%%Page" /* Second string to be searched */
#define SPACE_CHAR 0x20 /* space character */
#define NULL_CHAR 0x0 /* null character */
#define BACK_SLASH '\\' /* back slash character */
#define L_BRACKET '(' /* left bracket character */
#define R_BRACKET ')' /* right bracket character */
#define S_QUOTE '\'' /* single quotation mark */
#define D_QUOTE '"' /* double quotation mark */
#define TRUE 1 /* Logical constant */
#define FALSE 0 /* Logical constant */
#define KILO_BYTE 1024 /* machine related constant */
#define MAX_STR_LEN 512 /* Longest length of string allowed */
#define MAX_BUFR_SIZE (KILO_BYTE * 16) /* Define 16KB buffer size for */
/* both input and output file */
#define output_line(x) fprintf(outf, "%s\n", (x))
#define output_line_break fprintf(outf, "\n")
#define output_line_without_line_break(x) fprintf(outf, "%s", (x))
#ifndef __BORLANDC__
char inbufr[MAX_BUFR_SIZE]; /* reserve space for input file buffers */
char outbufr[MAX_BUFR_SIZE]; /* reserve space for output file buffers */
#endif
typedef int BOOL; /* Define boolean type */
FILE *inf; /* handle of input file */
FILE *outf; /* handle of output file */
FILE *errf; /* handle of error log file */
char Linebuff[MAX_STR_LEN]; /* pre-allocated input line buffer */
char Outbuff[MAX_STR_LEN]; /* pre-allocated output line buffer */
char Indcbuff[MAX_STR_LEN]; /* pre-allocated string buffer */
char Sub_string[MAX_STR_LEN]; /* pre-allocated string buffer */
char * pLinebuff; /* pointer to input line buffer */
char * pOutbuff; /* pointer to output line buffer */
char * pIndcbuff; /* pointer to string buffer */
char * pSubstr; /* pointer to another string buffer */
int pageno = 0; /* page number to be inserted into the page break */
int done = 0; /* indicator for end of line */
BOOL dp_error = FALSE; /* boolean variable */
/* when error happens it is set to be TRUE */
BOOL supress_page_break = FALSE; /* variable to decide whether */
/* output page break or not */
/* close all opened files */
/* write message to error log if necessary */
void closefiles(void)
{
fclose(inf);
fclose(outf);
if (!dp_error) fprintf(errf, "\nNo error.\n");
fclose(errf);
}
/* display and write to error log file a message about non-Postscript format */
void msgNonPS(void)
{
printf("\nError-->Non-Postcript input file.\n\n");
fprintf(errf, "\nError-->Non-Postcript input file.\n\n");
closefiles();
exit(-9);
}
/* writes a page break into output file */
void output_page_break()
{
pageno++;
if (!supress_page_break)
fprintf(outf, "\n\n============================ Page %i ===========================\n\n\n", pageno);
return;
}
/* copy characters between two pointers: p1 and p2 */
/* to the location starting: p0 */
/* if p2 is pointed to an address smaller than p1 */
/* this loop will terminate and NULL string returned */
char * getSubstring(char * p0, char * p1, char * p2)
{
char * temp1;
char * temp2;
/* copy characters */
temp1 = p0;
temp2 = p1;
/* terminate if p1 is pointed address after p2 */
if (p1 <= p2)
{
if (p1[0] == L_BRACKET)
{
/* search until right bracket is found */
while ((temp2[0] != R_BRACKET) && (temp2[0] != NULL_CHAR)) {
temp1[0] = temp2[0];
temp1++;
temp2++;
}
/* do not forget to copy the character pointed by: p2 */
temp1[0] = temp2[0];
}
else
{
/* just find the next space or EOL character */
while (temp2 != p2) {
temp1[0] = temp2[0];
temp1++;
temp2++;
}
/* do not forget to copy the character pointed by: p2 */
temp1[0] = temp2[0];
}
}
(++temp1)[0] = NULL_CHAR;
(++temp1)[0] = NULL_CHAR;
return temp2;
}
/* analyze the line read-in from input file */
/* source line pointer passed in by char * s1 */
/* pointer analyzed line stored and passed out by char * s2 */
int analyze_line(char * s1, char * s2)
{
int RC = 0;
char * c1;
char * c2;
char * c3;
char * c4;
char * c5;
int n_ptr;
char numero[MAX_STR_LEN];
c1 = s1;
c2 = s2;
/* set the analyze result string to be blank */
c2[0] = NULL_CHAR;
c2[1] = NULL_CHAR;
/* handle comment lines */
/* in Postscript, comment lines start with two percentage signs: "%%" */
if (strstr(c1, "%%") == c1) return RC;
while (c1[0])
{
/* skip spaces and TAB keys */
c3 = c1;
while ((c3[0] <= SPACE_CHAR) && (c3[0])) c3++;
/* at the end of input string */
if (!c3[0])
{
if (strlen(s2) > 0)
{
output_line_without_line_break(s2);
c2 = s2;
s2 = NULL_CHAR;
}
break;
}
/* starting of a word */
c1 = c3;
if (c1[0] != L_BRACKET)
{
if (c1[0] == R_BRACKET)
{
while ((c1[0] == SPACE_CHAR) || (c1[0] == R_BRACKET)) c1++;
c3 = c1;
}
while ((c3[0] > SPACE_CHAR) && (!c3[0])
&& (c3[0] != L_BRACKET) && (c3[0] != R_BRACKET)) c3++;
c3--;
/* getting of a sub-string */
c3 = getSubstring(pSubstr, c1, c3);
}
else
{
while ((c3[0] > SPACE_CHAR) && (!c3[0]) && (c3[0] != R_BRACKET))
{
if (c3[0] != BACK_SLASH)
c3++;
else
{
c3++;
c3++;
}
}
/* getting of a sub-string */
c3 = getSubstring(pSubstr, c1, c3);
}
/* update current char pointer */
c1 = c3;
c1++;
/* discriminate the token read-in */
switch (strlen(pSubstr))
{
case 0: break;
case 1: {
switch (pSubstr[0])
{
case 'y':
case 'T':
case 'P':
case 'Q':
{
c2[0] = NULL_CHAR;
if (strlen(s2) > 0)
output_line(s2);
else
output_line_break;
if (pSubstr[0] == 'Q')
output_line_break;
c2 = s2;
s2[0] = NULL_CHAR;
s2[1] = 0;
break;
}
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
{
/* between 'b' and 'k' */
c2[0] = SPACE_CHAR;
c2++;
c2[0] = NULL_CHAR;
break;
}
}
}
default: {
if (strcmp(pSubstr, "eop") == 0)
{
if (strlen(s2) > 0)
output_line(s2);
c2 = s2;
s2[0] = NULL_CHAR;
s2[1] = NULL_CHAR;
output_page_break();
break;
}
/* a displayable word entered */
if ((pSubstr[0] == L_BRACKET) && (pSubstr[strlen(pSubstr)-1] == R_BRACKET))
{
if (strchr(pSubstr, SPACE_CHAR) != NULL)
{
if (strstr(pSubstr, "(Error: )") != NULL) break;
if (strstr(pSubstr, "(converted error name will end") != NULL) break;
if (strstr(pSubstr, "(converted stack will end") != NULL) break;
if (strstr(pSubstr, "(Stack: )") != NULL) break;
if (strstr(pSubstr, "(Incompatable color bitimage") != NULL) break;
if (strstr(pSubstr, "(Offending Command:") != NULL) break;
}
c4 = pSubstr + 1;
while (!c4[0])
{
switch (c4[0])
{
case R_BRACKET:
c2[0] = 0;
c2--;
break;
case BACK_SLASH:
c4++;
if (!isdigit(c4[0]))
c2[0] = c4[0];
else
/* handle number */
{
c5 = c4;
n_ptr = 0;
while ((isdigit(c5[0])) && (n_ptr < 3)) {
numero[n_ptr++] = c5[0];
c5++;
}
numero[n_ptr] = 0;
switch (atoi(numero))
{
case 13:
(c2++)[0] = 'f';
c2[0] = 'f';
break;
case 14:
case 336:
(c2++)[0] = 'f';
c2[0] = 'i';
break;
case 322:
case 323:
c2[0] = D_QUOTE;
break;
case 324:
case 325:
c2[0] = S_QUOTE;
break;
case 134:
c2[0] = BACK_SLASH;
break;
case 50:
c2[0] = L_BRACKET;
break;
case 51:
c2[0] = R_BRACKET;
break;
case 245:
(c2++)[0] = '+';
c2[0] = SPACE_CHAR;
break;
default:c2[0] = (char) atoi(numero);
}
c4 = c5 - 1;
}
break;
default:
c2[0] = c4[0];
break;
}
}
c2++;
c4++;
c2[0] = NULL_CHAR;
break;
}
break;
}
} /* the biggest switch statement in this program */
}
/* flush line buffer if it is not empty */
if (strlen(s2) > 0)
output_line_without_line_break(s2);
s2[0] = NULL_CHAR;
s2[1] = NULL_CHAR;
return RC;
}
/* to check the first line of the file to tell */
/* if it is a Postscript formatted file */
void verifyPostscript(void)
{
/* read one non-blank line */
do {
fggets(pLinebuff, 1024, &done, inf);
} while (!strlen(pLinebuff));
/* check the Postscript indicator */
if (strstr(pLinebuff, "%!PS") != pLinebuff)
msgNonPS();
else
return;
}
/* to display usage on the stdio */
/* argument name is the program name */
void displayUsage(char * name)
{
char * ptr;
char * nameptr;
char nname[100];
strcpy(nname, name);
/* find the last back slash character */
ptr = strrchr(nname, BACK_SLASH);
if (ptr)
nameptr = ++ptr;
else
nameptr = name;
#ifdef __BORLANDC__
/* find the dot, then put a NULL-CHARACTER at that place */
ptr = strrchr(nname, '.');
if (ptr) ptr[0] = NULL;
#endif
#ifdef MSDOS
/* find the dot, then put a NULL-CHARACTER at that place */
if (ptr = strrchr(nname, '.')) ptr[0] = NULL_CHAR;
#endif
printf("\nUsage: %s PS-file-name [ -b ]", nameptr);
printf("\n (dump content of PS file onto the screen.)");
printf("\n\noptional -b: suppress page-break within output");
printf("\n\nother usage: %s PS-file-name [ -b ] > Text-file-name", nameptr);
printf("\n\n %s PS-file-name [ -b ] | more", nameptr);
printf("\n\nCopyright: David Yuan (C), Deakin University, May, 1996.\n\n");
fprintf(errf, "\nError-->No argument is supplied.\n\n");
fclose(errf);
}
/* Main body of the program */
void main(int argCount, char **argument)
{
/* to reserve space for both input and output file buffers */
#ifdef __BORLANDC__
char inbufr[MAX_BUFR_SIZE];
char outbufr[MAX_BUFR_SIZE];
#endif
/* To set up pointers to the text buffers, */
/* such arrangement make sure the program to be simple and fast */
/* no malloc() or free() function call is necessary */
/* set every bytes in these strings to be NULL char as precaution */
pLinebuff = (char *) (&Linebuff);
memset(pLinebuff, NULL_CHAR, MAX_STR_LEN - 1);
pOutbuff = (char *) (&Outbuff);
memset(pOutbuff, NULL_CHAR, MAX_STR_LEN - 1);
pIndcbuff = (char *) (&Indcbuff);
memset(pIndcbuff, NULL_CHAR, MAX_STR_LEN - 1);
pSubstr = (char *) (&Sub_string);
memset(pSubstr, NULL_CHAR, MAX_STR_LEN - 1);
/* pre-open the error log file */
errf = fopen("DPVIEW.ERROR", TEXT_WRITE);
/* handles arguments of the program */
/* display usage information if wrong number of arguments given */
if ((argCount < 2) || (argCount > 4))
{
displayUsage(argument[0]);
exit(0);
}
/* supress string */
if ((strcmp(argument[2], "-b") == 0)) supress_page_break = TRUE;
/* check the existance of the input file */
if (argCount >= 2)
{
if ((inf = fopen(argument[1], TEXT_READ)) == NULL)
{
printf("\nError-->File: %s can not be opened.\n\n", argument[1]);
fprintf(errf, "\nError-->File: %s can not be opened.\n\n", argument[1]);
fclose(inf);
fclose(errf);
exit(-1);
}
else
{
/* attempt to set up input file buffer */
if ((setvbuf(inf, (char *)(&inbufr), _IOLBF, MAX_BUFR_SIZE)) != 0)
{
printf("\nError-->System memory too low to execute program.\n\n");
fprintf(errf, "\nError-->System memory too low to execute program.\n\n");
fclose(inf);
fclose(errf);
exit(-5);
}
else
verifyPostscript();
}
}
/* dump output to screen */
outf = (FILE *) (stdout);
/* read in input file line by line */
/* until the first indicator string is found */
strcpy(pIndcbuff, INDICATOR_STR1);
while (!done)
{
fggets(pLinebuff, 1024, &done, inf);
if (strstr(pLinebuff, pIndcbuff) != NULL)
{
if ((feof(inf))) done = 1;
break;
}
}
/* read in input file line by line */
/* until the second indicator string is found */
/* The real PS text content begins from the next line */
strcpy(pIndcbuff, INDICATOR_STR2);
while (!done)
{
fggets(pLinebuff, 1024, &done, inf);
if (strstr(pLinebuff, pIndcbuff) != NULL)
{
if ((feof(inf))) done = 1;
break;
}
}
/* read in input file line by line */
/* analyze it and output plain text into output file */
do {
fggets(pLinebuff, 1024, &done, inf);
analyze_line(pLinebuff, pOutbuff);
if ((feof(inf))) done = 1;
} while (!done);
/* close input, output and error log files */
closefiles();
return;
}
/* End of main body of the program */
Commenti originali (3)
Recuperato da Wayback Machine