Logo Search packages:      
Sourcecode: pcal version File versions

pcalinit.c

/*
 * 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-1990  Jamie Zawinski  created.
 *
 * Revision history:
 *
 *    4.8.0 B.Marr      2004-11-15  Remove Ctl-L (page eject) characters 
 *                            from source file.  Remove spaces
 *                            embedded within tab fields.
 * 
 *    4.7   AWR   02/24/1998  include <stdlib.h> if available
 *
 *    4.5   AWR   04/05/1994  avoid adding block name comment if
 *                            first line already contains comment
 *
 *                12/08/1993  support #BEGIN <name>..#END blocks
 *                            for optional sections of PostScript
 *                            boilerplate (cf. writefil.c,
 *                            pcalinit.ps)
 *
 *                09/09/1993  propagate "%%" comments to output file
 *
 *    4.3   AWR   10/15/1991  minor tweak to avoid redefinition
 *                            of PROTOS
 *
 *    4.0   AWR   02/25/1991  added optional third argument for
 *                            name of array
 *
 *                02/19/1991  added function prototypes; documented
 *
 *                01/16/1991  Escape " and \ in quoted strings;
 *                            strip trailing comments; skip FF
 *
 *    2.6   JAB   10/18/1990  Add exit(0).
 *
 *    2.3   JWZ   09/14/1990  Author
 */

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#if defined(__STDC__) || defined(STDLIB)
#include <stdlib.h>
#endif

#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);
}

Generated by  Doxygen 1.6.0   Back to index