home *** CD-ROM | disk | FTP | other *** search
- /*
- * Create a .h file from a .ps file. Strips out leading and trailing
- * whitespace, blank lines, and lines consisting solely of comments,
- * except for the very first block of comments/blanklines, which are
- * turned into C comments at the top of the file.
- *
- * 14-sep-90 Jamie Zawinski created.
- *
- * Revision history:
- *
- * 4.5 AWR 04/05/94 avoid adding block name comment if
- * first line already contains comment
- *
- * 12/08/93 support #BEGIN <name>..#END blocks
- * for optional sections of PostScript
- * boilerplate (cf. writefil.c,
- * pcalinit.ps)
- *
- * 09/09/93 propagate "%%" comments to output file
- *
- * 4.3 AWR 10/15/91 minor tweak to avoid redefinition
- * of PROTOS
- *
- * 4.0 AWR 02/25/91 added optional third argument for
- * name of array
- *
- * 02/19/91 added function prototypes; documented
- *
- * 01/16/91 Escape " and \ in quoted strings;
- * strip trailing comments; skip FF
- *
- * 2.6 JAB 10/18/90 Add exit(0).
- *
- * 2.3 JWZ 09/14/90 Author
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
-
- #ifndef SEEK_SET /* symbolic definition for fseek() */
- #define SEEK_SET 0
- #endif
-
- #if !defined(PROTOS) && (defined(__STDC__) || defined(AMIGA))
- #define PROTOS
- #endif
-
- #define FALSE 0
- #define TRUE 1
-
- #define BEGIN_STR "#BEGIN" /* block delimiters */
- #define END_STR "#END"
-
- #define ARRAY_NAME "header" /* default name of array in .h file */
-
- #define IS_WHITESPACE(c) \
- ((c) == ' ' || (c) == '\t' || (c) == '\n' || c == '\f')
-
- #define IS_POSTSCRIPT(s) ((s)[0] != '%' && (s)[0] != '\0')
-
- #define IS_PSCOMMENT(s) ((s)[0] == '%' && (s)[1] == '%')
-
- #define IS_BEGIN(s) (strstr((s), BEGIN_STR) == (s))
-
- #define IS_END(s) (strstr((s), END_STR) == (s))
-
- /*
- * strip_white: strip leading and trailing whitespace from 'string'; return
- * pointer to first non-whitespace character
- */
- char *
- #ifdef PROTOS
- strip_white(char *string)
- #else
- strip_white(string)
- char *string;
- #endif
- {
- int n;
- for (; IS_WHITESPACE(*string); string++)
- ;
- n = strlen(string)-1;
- for (; IS_WHITESPACE(string[n]); n--)
- string[n] = '\0';
- return string;
- }
-
-
- /*
- * strip_comment: strip comment (unless denoted by "%%") and any preceding
- * whitespace from 'string'; return pointer to 'string'
- */
- char *
- #ifdef PROTOS
- strip_comment(char *string)
- #else
- strip_comment(string)
- char *string;
- #endif
- {
- char *p;
- if ((p = strchr(string, '%')) != NULL) {
- if (p[1] == '%') /* propagate '%%' comments */
- do
- p[0] = p[1]; /* squeeze out initial '%' */
- while (*++p);
- else
- *p = '\0'; /* delete '%' comments */
- string = strip_white(string);
- }
- return string;
- }
-
-
- /*
- * escape: copy string 'in' to string 'out', escaping the characters \ and ";
- * return pointer to 'out'
- */
- char *
- #ifdef PROTOS
- escape(char *out,
- char *in)
- #else
- escape(out, in)
- char *out, *in;
- #endif
- {
- char c, *sv_out = out;
-
- for (; c = *in; *out++ = *in++)
- if (c == '\\' || c == '"')
- *out++ = '\\';
-
- *out = '\0';
- return sv_out;
- }
-
-
- int
- #ifdef PROTOS
- main(int argc,
- char *argv[])
- #else
- main(argc, argv)
- int argc;
- char *argv[];
- #endif
- {
- FILE *in, *out;
- char line[256], line2[512], *L, *array, *p, blockname[80];
- int in_initial_comments, in_block, lineno;
-
- /* retrieve arguments and attempt to open input and output files */
-
- if (argc < 3 || argc > 4) {
- fprintf(stderr, "usage: %s <infile>.ps <outfile>.h [<arrayname>]\n",
- argv[0]);
- exit(-1); }
-
- in = fopen(argv[1], "r");
- if (NULL == in) {
- fprintf(stderr, "%s: couldn't open %s\n", argv[0], argv[1]);
- exit(-1); }
-
- out = fopen(argv[2], "w");
- if (NULL == out) {
- fprintf(stderr, "%s: couldn't open %s\n", argv[0], argv[2]);
- exit(-1); }
-
- array = argc == 4 ? argv[3] : ARRAY_NAME;
-
- /* print topline comment on output file */
-
- fprintf (out, "/*\n * %s: automatically generated by %s from %s\n",
- argv[2], argv[0], argv[1]);
- fprintf (out, " *\n *\tDO NOT EDIT THIS FILE!\n *\n");
-
- /*
- * main loop - copy lines from input file, to output file, preserving
- * only initial block of comments and blank lines and skipping
- * over #BEGIN..#END blocks
- */
-
- in_block = FALSE;
- in_initial_comments = TRUE;
- for (lineno = 1; fgets(line, 255, in) != NULL; lineno++ ) {
- L = strip_white(line); /* strip whitespace */
-
- if ( IS_POSTSCRIPT(L) || /* PostScript source or */
- IS_PSCOMMENT(L) ) { /* comment to propagate? */
- if ( in_initial_comments ) { /* first PS line? */
- in_initial_comments = FALSE;
- fprintf(out, " */\n\nchar *%s[] = {\n", array);
- }
- if (IS_PSCOMMENT(L))
- L++; /* drop first % from %% */
- else
- L = strip_comment(L); /* strip trailing comment */
- if (IS_BEGIN(L)) {
- if (in_block) {
- fprintf(stderr, "%s: #BEGIN nesting error in %s (line %d)\n",
- argv[0], argv[1], lineno);
- exit(-1);
- }
- in_block = TRUE;
- }
- else if (IS_END(L)) {
- if (!in_block) {
- fprintf(stderr, "%s: #END nesting error in %s (line %d)\n",
- argv[0], argv[1], lineno);
- exit(-1);
- }
- in_block = FALSE;
- }
- else if (!in_block) {
- L = escape(line2, L);
- fprintf(out, " \"%s\",\n", L);
- }
- } else
- /* blank or comment line - copy only if in initial comment block */
- if ( in_initial_comments )
- fprintf(out, " * %s\n", L);
- }
-
- fprintf(out, " (char *)0,\n};\n"); /* terminate array decl */
-
- if (in_block) { /* unterminated block? */
- fprintf(stderr, "%s: unterminated #BEGIN..#END block in %s\n",
- argv[0], argv[1]);
- exit(-1);
- }
-
- /*
- * second loop - copy only lines within #BEGIN .. #END blocks
- */
-
- fseek(in, 0L, SEEK_SET); /* rewind */
- in_block = FALSE;
- blockname[0] = '\0';
-
- while ( fgets(line, 255, in) != NULL ) {
- L = strip_white(line); /* strip whitespace */
- if ( IS_POSTSCRIPT(L) ) {
- L = strip_comment(L); /* strip trailing comment */
- if (IS_BEGIN(L)) {
- in_block = TRUE;
- for (p = L + strlen(BEGIN_STR); *p && IS_WHITESPACE(*p); p++)
- ;
- fprintf(out, "\nchar *%s[] = {\n", p);
- strcpy(blockname, p);
- }
- else if (IS_END(L)) {
- fprintf(out, " (char *)0,\n};\n"); /* terminate array decl */
- in_block = FALSE;
- }
- else if (in_block) {
- /* copy PostScript to output file; add block name to first line */
- L = escape(line2, L);
- fprintf(out, " \"%s", L);
- if (blockname[0] && !strchr(L, '%'))
- fprintf(out, "\\t\\t\\t%% %s", blockname);
- blockname[0] = '\0';
- fprintf(out, "\",\n");
- }
- }
- }
-
- fclose(out); /* close files and exit */
- fclose(in);
- exit (0);
- }
-