Back to index

tetex-bin  3.0
squeeze.c
Go to the documentation of this file.
00001 /*========================================================================*\
00002 
00003 Copyright (c) 1994-2004  Paul Vojta
00004 
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to
00007 deal in the Software without restriction, including without limitation the
00008 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00009 sell copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011 
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00018 PAUL VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM,
00019 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00020 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00021 OTHER DEALINGS IN THE SOFTWARE.
00022 
00023 NOTE:
00024        This routine is adapted from the squeeze.c that comes with dvips;
00025        it bears the message:
00026            This software is Copyright 1988 by Radical Eye Software.
00027        Used with permission.
00028 
00029 \*========================================================================*/
00030 
00031 /*
00032  *   This routine squeezes a PostScript file down to its
00033  *   minimum.  We parse and then output it.
00034  *   Adapted for xdvi 1/94.  Writes a C program that contains the PS file
00035  *   as a constant string.
00036  */
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include "kpathsea/c-auto.h"
00040 #include "kpathsea/c-memstr.h"
00041 
00042 #ifndef EXIT_SUCCESS
00043 #define EXIT_SUCCESS 0
00044 #endif
00045 #ifndef EXIT_FAILURE
00046 #define EXIT_FAILURE 1
00047 #endif
00048 
00049 
00050 #define LINELENGTH (72)
00051 #define BUFLENGTH (1000)
00052 #undef putchar
00053 #define putchar(a) (void)putc(a, out) ;
00054 FILE *in, *out;
00055 static int linepos = 0;
00056 static int lastspecial = 1;
00057 static int stringlen = 0;
00058 /*
00059  *   This next routine writes out a `special' character.  In this case,
00060  *   we simply put it out, since any special character terminates the
00061  *   preceding token.
00062  */
00063 static void
00064 specialout(char c)
00065 {
00066     if (linepos + 1 > LINELENGTH) {
00067        (void)fputs("\\n\\\n", out);
00068        stringlen += linepos + 1;
00069        linepos = 0;
00070     }
00071     putchar(c);
00072     linepos++;
00073     lastspecial = 1;
00074 }
00075 
00076 static void
00077 strout(char *s)
00078 {
00079     if (linepos + strlen(s) > LINELENGTH) {
00080        (void)fputs("\\n\\\n", out);
00081        stringlen += linepos + 1;
00082        linepos = 0;
00083     }
00084     linepos += strlen(s);
00085     while (*s != 0)
00086        putchar(*s++);
00087     lastspecial = 1;
00088 }
00089 
00090 static void
00091 cmdout(char *s)
00092 {
00093     int l;
00094 
00095     l = strlen(s);
00096     if (linepos + l + 1 > LINELENGTH) {
00097        (void)fputs("\\n\\\n", out);
00098        stringlen += linepos + 1;
00099        linepos = 0;
00100        lastspecial = 1;
00101     }
00102     if (!lastspecial) {
00103        putchar(' ');
00104        linepos++;
00105     }
00106     while (*s != 0) {
00107        putchar(*s++);
00108     }
00109     linepos += l;
00110     lastspecial = 0;
00111 }
00112 
00113 char buf[BUFLENGTH];
00114 #ifndef VMS
00115 int
00116 #endif
00117 main(int argc, char *argv[])
00118 {
00119     int c;
00120     char *b;
00121     char seeking;
00122     extern void exit();
00123 
00124     if (argc > 3 || (in = (argc < 2 ? stdin : fopen(argv[1], "r"))) == NULL ||
00125        (out = (argc < 3 ? stdout : fopen(argv[2], "w"))) == NULL) {
00126        (void)fprintf(stderr, "Usage:  squeeze [infile [outfile]]\n");
00127        exit(EXIT_FAILURE);
00128     }
00129     (void)fputs("/*\n"
00130               " *   DO NOT EDIT THIS FILE!\n"
00131               " *   It was created by squeeze.c from another file (see the Makefile).\n"
00132               " */\n\n"
00133               "const char psheader[] = \"\\\n", out);
00134     while (1) {
00135        c = getc(in);
00136        if (c == EOF)
00137            break;
00138        if (c == '%') {
00139            while ((c = getc(in)) != '\n');
00140        }
00141        if (c <= ' ')
00142            continue;
00143        switch (c) {
00144        case '{':
00145        case '}':
00146        case '[':
00147        case ']':
00148            specialout(c);
00149            break;
00150        case '<':
00151        case '(':
00152            if (c == '(')
00153               seeking = ')';
00154            else
00155               seeking = '>';
00156            b = buf;
00157            *b++ = c;
00158            do {
00159               c = getc(in);
00160               if (b > buf + BUFLENGTH - 2) {
00161                   (void)fprintf(stderr, "Overran buffer seeking %c", seeking);
00162                   exit(EXIT_FAILURE);
00163               }
00164               *b++ = c;
00165               if (c == '\\')
00166                   *b++ = getc(in);
00167            } while (c != seeking);
00168            *b++ = 0;
00169            strout(buf);
00170            break;
00171        default:
00172            b = buf;
00173            while ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
00174                  (c >= '0' && c <= '9') || (c == '/') || (c == '@') ||
00175                  (c == '!') || (c == '"') || (c == '&') || (c == '*')
00176                  || (c == ':') || (c == ',') || (c == ';') || (c == '?')
00177                  || (c == '^') || (c == '~') || (c == '-') || (c == '.')
00178                  || (c == '#') || (c == '|') || (c == '_') || (c == '=')
00179                  || (c == '$') || (c == '+')) {
00180               *b++ = c;
00181               c = getc(in);
00182            }
00183            if (b == buf) {
00184               (void)fprintf(stderr, "Oops!  Missed a case: %c.\n", c);
00185               exit(EXIT_FAILURE);
00186            }
00187            *b++ = 0;
00188            (void)ungetc(c, in);
00189            cmdout(buf);
00190        }
00191     }
00192     (void)fprintf(out,
00193                 "\\n\";\n\n int\tpsheaderlen\t= %d;\n",
00194                 stringlen + linepos + 1);
00195     return 0;
00196 }