JavaScript, Json minimizator

jsmin – is a JavaScript, Json minimizator which removes comments and unnecessary whitespace from JS, JSON files

2 Commits   0 Branches   0 Tags
f8470165 (kx 2023-04-07 06:34:02 +0300   1) 
f8470165 (kx 2023-04-07 06:34:02 +0300   2) #ifdef HAVE_CONFIG_H
f8470165 (kx 2023-04-07 06:34:02 +0300   3) #include <config.h>
f8470165 (kx 2023-04-07 06:34:02 +0300   4) 
f8470165 (kx 2023-04-07 06:34:02 +0300   5) #ifdef HAVE_FCNTL_H
f8470165 (kx 2023-04-07 06:34:02 +0300   6) #include <fcntl.h>
f8470165 (kx 2023-04-07 06:34:02 +0300   7) #endif
f8470165 (kx 2023-04-07 06:34:02 +0300   8) #ifdef HAVE_UNISTD_H
f8470165 (kx 2023-04-07 06:34:02 +0300   9) #include <unistd.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  10) #endif
f8470165 (kx 2023-04-07 06:34:02 +0300  11) 
f8470165 (kx 2023-04-07 06:34:02 +0300  12) #ifdef HAVE_SYS_STAT_H
f8470165 (kx 2023-04-07 06:34:02 +0300  13) #include <sys/stat.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  14) #endif
f8470165 (kx 2023-04-07 06:34:02 +0300  15) 
f8470165 (kx 2023-04-07 06:34:02 +0300  16) #ifdef HAVE_ERRNO_H
f8470165 (kx 2023-04-07 06:34:02 +0300  17) #include <errno.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  18) #endif
f8470165 (kx 2023-04-07 06:34:02 +0300  19) #ifdef HAVE_STRING_H
f8470165 (kx 2023-04-07 06:34:02 +0300  20) #include <string.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  21) #endif
f8470165 (kx 2023-04-07 06:34:02 +0300  22) 
f8470165 (kx 2023-04-07 06:34:02 +0300  23) #ifdef HAVE_STDLIB_H
f8470165 (kx 2023-04-07 06:34:02 +0300  24) #include <stdlib.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  25) #endif
f8470165 (kx 2023-04-07 06:34:02 +0300  26) #ifdef HAVE_STDIO_H
f8470165 (kx 2023-04-07 06:34:02 +0300  27) #include <stdio.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  28) #endif
f8470165 (kx 2023-04-07 06:34:02 +0300  29) #ifdef HAVE_GETOPT_H
f8470165 (kx 2023-04-07 06:34:02 +0300  30) #include <getopt.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  31) #endif
f8470165 (kx 2023-04-07 06:34:02 +0300  32) 
f8470165 (kx 2023-04-07 06:34:02 +0300  33) #else
f8470165 (kx 2023-04-07 06:34:02 +0300  34) /**************************************************************
f8470165 (kx 2023-04-07 06:34:02 +0300  35)   For building outside from source package as a single C file:
f8470165 (kx 2023-04-07 06:34:02 +0300  36) 
f8470165 (kx 2023-04-07 06:34:02 +0300  37)     $ gcc -o jsmin main.c
f8470165 (kx 2023-04-07 06:34:02 +0300  38)  */
f8470165 (kx 2023-04-07 06:34:02 +0300  39) 
f8470165 (kx 2023-04-07 06:34:02 +0300  40) #include <fcntl.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  41) #include <unistd.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  42) 
f8470165 (kx 2023-04-07 06:34:02 +0300  43) #include <sys/stat.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  44) 
f8470165 (kx 2023-04-07 06:34:02 +0300  45) #include <errno.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  46) #include <string.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  47) 
f8470165 (kx 2023-04-07 06:34:02 +0300  48) #include <stdlib.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  49) #include <stdio.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  50) #include <getopt.h>
f8470165 (kx 2023-04-07 06:34:02 +0300  51) 
f8470165 (kx 2023-04-07 06:34:02 +0300  52) #endif
f8470165 (kx 2023-04-07 06:34:02 +0300  53) 
f8470165 (kx 2023-04-07 06:34:02 +0300  54) static char *ifname   = NULL;
f8470165 (kx 2023-04-07 06:34:02 +0300  55) static char *ofname   = NULL;
f8470165 (kx 2023-04-07 06:34:02 +0300  56) 
f8470165 (kx 2023-04-07 06:34:02 +0300  57) FILE        *ifile;
f8470165 (kx 2023-04-07 06:34:02 +0300  58) FILE        *ofile;
f8470165 (kx 2023-04-07 06:34:02 +0300  59) FILE        *tmp;
f8470165 (kx 2023-04-07 06:34:02 +0300  60) 
f8470165 (kx 2023-04-07 06:34:02 +0300  61) static char *progname = NULL;
f8470165 (kx 2023-04-07 06:34:02 +0300  62) 
f8470165 (kx 2023-04-07 06:34:02 +0300  63) static int   opt_usage;
f8470165 (kx 2023-04-07 06:34:02 +0300  64) static int   opt_version;
f8470165 (kx 2023-04-07 06:34:02 +0300  65) 
f8470165 (kx 2023-04-07 06:34:02 +0300  66) #define DIR_SEPARATOR '/'
f8470165 (kx 2023-04-07 06:34:02 +0300  67) 
f8470165 (kx 2023-04-07 06:34:02 +0300  68) static void usage()
f8470165 (kx 2023-04-07 06:34:02 +0300  69) {
f8470165 (kx 2023-04-07 06:34:02 +0300  70)   printf( "\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  71)   printf( "Usage: %s [options] [input_file_name]\n", progname );
f8470165 (kx 2023-04-07 06:34:02 +0300  72)   printf( "Options:\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  73)   printf( "   --output | -o       - output file name;\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  74)   printf( "   --version | -v      - print version numver;\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  75)   printf( "   --help | -h | -?    - print this message;\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  76)   printf( "   --                  - an option terminator;\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  77)   printf( "   -                   - use std{io|out} instead of files.\n\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  78)   printf( "Examples:\n\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  79)   printf( "  Input file is 'full.json', output file is 'min.json':\n\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  80)   printf( "    $ %s -o min.json full.json\n\n", progname );
f8470165 (kx 2023-04-07 06:34:02 +0300  81)   printf( "  Input file is 'STDIN', output file is 'min.json':\n\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  82)   printf( "    $ %s -o min.json -\n\n", progname );
f8470165 (kx 2023-04-07 06:34:02 +0300  83)   printf( "    Please note that to terminate your input by keyboard you have to use\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  84)   printf( "    <Ctrl>+d combination;\n\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  85)   printf( "  Input file is 'full.json', output file is 'STDOUT':\n\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  86)   printf( "    $ %s -- full.json\n\n", progname );
f8470165 (kx 2023-04-07 06:34:02 +0300  87)   printf( "  Use stdin, stdout:\n\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  88)   printf( "    $ %s - < full.json > min.json\n\n", progname );
f8470165 (kx 2023-04-07 06:34:02 +0300  89)   printf( "Enjoj.\n\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300  90) 
f8470165 (kx 2023-04-07 06:34:02 +0300  91)   exit( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300  92) }
f8470165 (kx 2023-04-07 06:34:02 +0300  93) 
f8470165 (kx 2023-04-07 06:34:02 +0300  94) static void version()
f8470165 (kx 2023-04-07 06:34:02 +0300  95) {
f8470165 (kx 2023-04-07 06:34:02 +0300  96) #ifdef HAVE_CONFIG_H
f8470165 (kx 2023-04-07 06:34:02 +0300  97)   printf( "%s\n", (char *)VERSION );
f8470165 (kx 2023-04-07 06:34:02 +0300  98) #else
f8470165 (kx 2023-04-07 06:34:02 +0300  99)   printf( "0.0.1\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300 100) #endif
f8470165 (kx 2023-04-07 06:34:02 +0300 101) 
f8470165 (kx 2023-04-07 06:34:02 +0300 102)   exit( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300 103) }
f8470165 (kx 2023-04-07 06:34:02 +0300 104) 
f8470165 (kx 2023-04-07 06:34:02 +0300 105) static void
f8470165 (kx 2023-04-07 06:34:02 +0300 106) error( char *s )
f8470165 (kx 2023-04-07 06:34:02 +0300 107) {
f8470165 (kx 2023-04-07 06:34:02 +0300 108)   fprintf( stderr, "ERROR: %s: ", progname );
f8470165 (kx 2023-04-07 06:34:02 +0300 109)   fprintf( stderr, "%s\n", s );
f8470165 (kx 2023-04-07 06:34:02 +0300 110)   exit( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300 111) }
f8470165 (kx 2023-04-07 06:34:02 +0300 112) 
f8470165 (kx 2023-04-07 06:34:02 +0300 113) static int
f8470165 (kx 2023-04-07 06:34:02 +0300 114) is_alpha_or_num( int c )
f8470165 (kx 2023-04-07 06:34:02 +0300 115) {
f8470165 (kx 2023-04-07 06:34:02 +0300 116)   return( (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
f8470165 (kx 2023-04-07 06:34:02 +0300 117)           (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c == '\\' || c > 126 );
f8470165 (kx 2023-04-07 06:34:02 +0300 118) }
f8470165 (kx 2023-04-07 06:34:02 +0300 119) 
f8470165 (kx 2023-04-07 06:34:02 +0300 120) static int  a;
f8470165 (kx 2023-04-07 06:34:02 +0300 121) static int  b;
f8470165 (kx 2023-04-07 06:34:02 +0300 122) static int  lookahead = EOF;
f8470165 (kx 2023-04-07 06:34:02 +0300 123) static int  x = EOF;
f8470165 (kx 2023-04-07 06:34:02 +0300 124) static int  y = EOF;
f8470165 (kx 2023-04-07 06:34:02 +0300 125) 
f8470165 (kx 2023-04-07 06:34:02 +0300 126) /*
f8470165 (kx 2023-04-07 06:34:02 +0300 127)    get - return the next character from stdin. Watch out for lookahead. If
f8470165 (kx 2023-04-07 06:34:02 +0300 128)          the character is a control character, translate it to a space or
f8470165 (kx 2023-04-07 06:34:02 +0300 129)          linefeed.
f8470165 (kx 2023-04-07 06:34:02 +0300 130)  */
f8470165 (kx 2023-04-07 06:34:02 +0300 131) static int
f8470165 (kx 2023-04-07 06:34:02 +0300 132) get()
f8470165 (kx 2023-04-07 06:34:02 +0300 133) {
f8470165 (kx 2023-04-07 06:34:02 +0300 134)   int c = lookahead;
f8470165 (kx 2023-04-07 06:34:02 +0300 135)   lookahead = EOF;
f8470165 (kx 2023-04-07 06:34:02 +0300 136)   if( c == EOF )
f8470165 (kx 2023-04-07 06:34:02 +0300 137)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 138)     c = getc( ifile );
f8470165 (kx 2023-04-07 06:34:02 +0300 139)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 140)   if( c >= ' ' || c == '\n' || c == EOF )
f8470165 (kx 2023-04-07 06:34:02 +0300 141)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 142)     return c;
f8470165 (kx 2023-04-07 06:34:02 +0300 143)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 144)   if( c == '\r' )
f8470165 (kx 2023-04-07 06:34:02 +0300 145)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 146)     return '\n';
f8470165 (kx 2023-04-07 06:34:02 +0300 147)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 148)   return ' ';
f8470165 (kx 2023-04-07 06:34:02 +0300 149) }
f8470165 (kx 2023-04-07 06:34:02 +0300 150) 
f8470165 (kx 2023-04-07 06:34:02 +0300 151) 
f8470165 (kx 2023-04-07 06:34:02 +0300 152) /*
f8470165 (kx 2023-04-07 06:34:02 +0300 153)    peek - get the next character without getting it.
f8470165 (kx 2023-04-07 06:34:02 +0300 154)  */
f8470165 (kx 2023-04-07 06:34:02 +0300 155) static int
f8470165 (kx 2023-04-07 06:34:02 +0300 156) peek()
f8470165 (kx 2023-04-07 06:34:02 +0300 157) {
f8470165 (kx 2023-04-07 06:34:02 +0300 158)   lookahead = get();
f8470165 (kx 2023-04-07 06:34:02 +0300 159)   return lookahead;
f8470165 (kx 2023-04-07 06:34:02 +0300 160) }
f8470165 (kx 2023-04-07 06:34:02 +0300 161) 
f8470165 (kx 2023-04-07 06:34:02 +0300 162) 
f8470165 (kx 2023-04-07 06:34:02 +0300 163) /*
f8470165 (kx 2023-04-07 06:34:02 +0300 164)    next - get the next character, excluding comments. peek() is used to see
f8470165 (kx 2023-04-07 06:34:02 +0300 165)           if a '/' is followed by a '/' or '*'.
f8470165 (kx 2023-04-07 06:34:02 +0300 166)  */
f8470165 (kx 2023-04-07 06:34:02 +0300 167) static int
f8470165 (kx 2023-04-07 06:34:02 +0300 168) next()
f8470165 (kx 2023-04-07 06:34:02 +0300 169) {
f8470165 (kx 2023-04-07 06:34:02 +0300 170)   int c = get();
f8470165 (kx 2023-04-07 06:34:02 +0300 171)   if ( c == '/' )
f8470165 (kx 2023-04-07 06:34:02 +0300 172)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 173)     switch( peek() )
f8470165 (kx 2023-04-07 06:34:02 +0300 174)     {
f8470165 (kx 2023-04-07 06:34:02 +0300 175)       case '/':
f8470165 (kx 2023-04-07 06:34:02 +0300 176)         for( ;; )
f8470165 (kx 2023-04-07 06:34:02 +0300 177)         {
f8470165 (kx 2023-04-07 06:34:02 +0300 178)           c = get();
f8470165 (kx 2023-04-07 06:34:02 +0300 179)           if( c <= '\n' )
f8470165 (kx 2023-04-07 06:34:02 +0300 180)           {
f8470165 (kx 2023-04-07 06:34:02 +0300 181)             break;
f8470165 (kx 2023-04-07 06:34:02 +0300 182)           }
f8470165 (kx 2023-04-07 06:34:02 +0300 183)         }
f8470165 (kx 2023-04-07 06:34:02 +0300 184)         break;
f8470165 (kx 2023-04-07 06:34:02 +0300 185)       case '*':
f8470165 (kx 2023-04-07 06:34:02 +0300 186)         get();
f8470165 (kx 2023-04-07 06:34:02 +0300 187)         while( c != ' ' )
f8470165 (kx 2023-04-07 06:34:02 +0300 188)         {
f8470165 (kx 2023-04-07 06:34:02 +0300 189)           switch( get() )
f8470165 (kx 2023-04-07 06:34:02 +0300 190)           {
f8470165 (kx 2023-04-07 06:34:02 +0300 191)             case '*':
f8470165 (kx 2023-04-07 06:34:02 +0300 192)               if( peek() == '/' )
f8470165 (kx 2023-04-07 06:34:02 +0300 193)               {
f8470165 (kx 2023-04-07 06:34:02 +0300 194)                 get();
f8470165 (kx 2023-04-07 06:34:02 +0300 195)                 c = ' ';
f8470165 (kx 2023-04-07 06:34:02 +0300 196)               }
f8470165 (kx 2023-04-07 06:34:02 +0300 197)               break;
f8470165 (kx 2023-04-07 06:34:02 +0300 198)             case EOF:
f8470165 (kx 2023-04-07 06:34:02 +0300 199)               error( "Unterminated comment" );
f8470165 (kx 2023-04-07 06:34:02 +0300 200)           }
f8470165 (kx 2023-04-07 06:34:02 +0300 201)         }
f8470165 (kx 2023-04-07 06:34:02 +0300 202)         break;
f8470165 (kx 2023-04-07 06:34:02 +0300 203)     }
f8470165 (kx 2023-04-07 06:34:02 +0300 204)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 205)   y = x;
f8470165 (kx 2023-04-07 06:34:02 +0300 206)   x = c;
f8470165 (kx 2023-04-07 06:34:02 +0300 207)   return c;
f8470165 (kx 2023-04-07 06:34:02 +0300 208) }
f8470165 (kx 2023-04-07 06:34:02 +0300 209) 
f8470165 (kx 2023-04-07 06:34:02 +0300 210) 
f8470165 (kx 2023-04-07 06:34:02 +0300 211) /*
f8470165 (kx 2023-04-07 06:34:02 +0300 212)    action - do something! What you do is determined by the argument:
f8470165 (kx 2023-04-07 06:34:02 +0300 213)             1   Output A. Copy B to A. Get the next B.
f8470165 (kx 2023-04-07 06:34:02 +0300 214)             2   Copy B to A. Get the next B. (Delete A).
f8470165 (kx 2023-04-07 06:34:02 +0300 215)             3   Get the next B. (Delete B).
f8470165 (kx 2023-04-07 06:34:02 +0300 216)    action treats a string as a single character. Wow!
f8470165 (kx 2023-04-07 06:34:02 +0300 217)    action recognizes a regular expression if it is preceded by ( or , or =.
f8470165 (kx 2023-04-07 06:34:02 +0300 218)  */
f8470165 (kx 2023-04-07 06:34:02 +0300 219) static void
f8470165 (kx 2023-04-07 06:34:02 +0300 220) action( int d )
f8470165 (kx 2023-04-07 06:34:02 +0300 221) {
f8470165 (kx 2023-04-07 06:34:02 +0300 222)   switch( d )
f8470165 (kx 2023-04-07 06:34:02 +0300 223)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 224)     case 1:
f8470165 (kx 2023-04-07 06:34:02 +0300 225)       putc( a, ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 226)       if( (y == '\n' || y == ' ') &&
f8470165 (kx 2023-04-07 06:34:02 +0300 227)           (a == '+' || a == '-' || a == '*' || a == '/') &&
f8470165 (kx 2023-04-07 06:34:02 +0300 228)           (b == '+' || b == '-' || b == '*' || b == '/')    )
f8470165 (kx 2023-04-07 06:34:02 +0300 229)       {
f8470165 (kx 2023-04-07 06:34:02 +0300 230)         putc( y, ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 231)       }
f8470165 (kx 2023-04-07 06:34:02 +0300 232)     case 2:
f8470165 (kx 2023-04-07 06:34:02 +0300 233)       a = b;
f8470165 (kx 2023-04-07 06:34:02 +0300 234)       if( a == '\'' || a == '"' || a == '`' )
f8470165 (kx 2023-04-07 06:34:02 +0300 235)       {
f8470165 (kx 2023-04-07 06:34:02 +0300 236)         for( ;; )
f8470165 (kx 2023-04-07 06:34:02 +0300 237)         {
f8470165 (kx 2023-04-07 06:34:02 +0300 238)           putc( a, ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 239)           a = get();
f8470165 (kx 2023-04-07 06:34:02 +0300 240)           if( a == b )
f8470165 (kx 2023-04-07 06:34:02 +0300 241)           {
f8470165 (kx 2023-04-07 06:34:02 +0300 242)             break;
f8470165 (kx 2023-04-07 06:34:02 +0300 243)           }
f8470165 (kx 2023-04-07 06:34:02 +0300 244)           if( a == '\\' )
f8470165 (kx 2023-04-07 06:34:02 +0300 245)           {
f8470165 (kx 2023-04-07 06:34:02 +0300 246)             putc( a, ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 247)             a = get();
f8470165 (kx 2023-04-07 06:34:02 +0300 248)           }
f8470165 (kx 2023-04-07 06:34:02 +0300 249)           if( a == EOF )
f8470165 (kx 2023-04-07 06:34:02 +0300 250)           {
f8470165 (kx 2023-04-07 06:34:02 +0300 251)             error( "Unterminated string literal" );
f8470165 (kx 2023-04-07 06:34:02 +0300 252)           }
f8470165 (kx 2023-04-07 06:34:02 +0300 253)         }
f8470165 (kx 2023-04-07 06:34:02 +0300 254)       }
f8470165 (kx 2023-04-07 06:34:02 +0300 255)     case 3:
f8470165 (kx 2023-04-07 06:34:02 +0300 256)       b = next();
f8470165 (kx 2023-04-07 06:34:02 +0300 257)       if( b == '/' &&
f8470165 (kx 2023-04-07 06:34:02 +0300 258)           ( a == '(' || a == ',' || a == '=' || a == ':' ||
f8470165 (kx 2023-04-07 06:34:02 +0300 259)             a == '[' || a == '!' || a == '&' || a == '|' ||
f8470165 (kx 2023-04-07 06:34:02 +0300 260)             a == '?' || a == '+' || a == '-' || a == '~' ||
f8470165 (kx 2023-04-07 06:34:02 +0300 261)             a == '*' || a == '/' || a == '{' || a == '\n' ) )
f8470165 (kx 2023-04-07 06:34:02 +0300 262)       {
f8470165 (kx 2023-04-07 06:34:02 +0300 263)         putc( a, ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 264)         if( a == '/' || a == '*' )
f8470165 (kx 2023-04-07 06:34:02 +0300 265)         {
f8470165 (kx 2023-04-07 06:34:02 +0300 266)           putc( ' ', ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 267)         }
f8470165 (kx 2023-04-07 06:34:02 +0300 268)         putc( b, ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 269)         for( ;; )
f8470165 (kx 2023-04-07 06:34:02 +0300 270)         {
f8470165 (kx 2023-04-07 06:34:02 +0300 271)           a = get();
f8470165 (kx 2023-04-07 06:34:02 +0300 272)           if( a == '[' )
f8470165 (kx 2023-04-07 06:34:02 +0300 273)           {
f8470165 (kx 2023-04-07 06:34:02 +0300 274)             for( ;; )
f8470165 (kx 2023-04-07 06:34:02 +0300 275)             {
f8470165 (kx 2023-04-07 06:34:02 +0300 276)               putc( a, ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 277)               a = get();
f8470165 (kx 2023-04-07 06:34:02 +0300 278)               if( a == ']' )
f8470165 (kx 2023-04-07 06:34:02 +0300 279)               {
f8470165 (kx 2023-04-07 06:34:02 +0300 280)                 break;
f8470165 (kx 2023-04-07 06:34:02 +0300 281)               }
f8470165 (kx 2023-04-07 06:34:02 +0300 282)               if( a == '\\' )
f8470165 (kx 2023-04-07 06:34:02 +0300 283)               {
f8470165 (kx 2023-04-07 06:34:02 +0300 284)                 putc( a, ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 285)                 a = get();
f8470165 (kx 2023-04-07 06:34:02 +0300 286)               }
f8470165 (kx 2023-04-07 06:34:02 +0300 287)               if( a == EOF )
f8470165 (kx 2023-04-07 06:34:02 +0300 288)               {
f8470165 (kx 2023-04-07 06:34:02 +0300 289)                 error( "Unterminated set in Regular Expression literal" );
f8470165 (kx 2023-04-07 06:34:02 +0300 290)               }
f8470165 (kx 2023-04-07 06:34:02 +0300 291)             }
f8470165 (kx 2023-04-07 06:34:02 +0300 292)           }
f8470165 (kx 2023-04-07 06:34:02 +0300 293)           else if( a == '/' )
f8470165 (kx 2023-04-07 06:34:02 +0300 294)           {
f8470165 (kx 2023-04-07 06:34:02 +0300 295)             switch( peek() )
f8470165 (kx 2023-04-07 06:34:02 +0300 296)             {
f8470165 (kx 2023-04-07 06:34:02 +0300 297)               case '/':
f8470165 (kx 2023-04-07 06:34:02 +0300 298)               case '*':
f8470165 (kx 2023-04-07 06:34:02 +0300 299)                 error( "Unterminated set in Regular Expression literal" );
f8470165 (kx 2023-04-07 06:34:02 +0300 300)             }
f8470165 (kx 2023-04-07 06:34:02 +0300 301)             break;
f8470165 (kx 2023-04-07 06:34:02 +0300 302)           }
f8470165 (kx 2023-04-07 06:34:02 +0300 303)           else if( a =='\\' )
f8470165 (kx 2023-04-07 06:34:02 +0300 304)           {
f8470165 (kx 2023-04-07 06:34:02 +0300 305)             putc( a, ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 306)             a = get();
f8470165 (kx 2023-04-07 06:34:02 +0300 307)           }
f8470165 (kx 2023-04-07 06:34:02 +0300 308)           if( a == EOF )
f8470165 (kx 2023-04-07 06:34:02 +0300 309)           {
f8470165 (kx 2023-04-07 06:34:02 +0300 310)             error( "Unterminated Regular Expression literal" );
f8470165 (kx 2023-04-07 06:34:02 +0300 311)           }
f8470165 (kx 2023-04-07 06:34:02 +0300 312)           putc( a, ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 313)         }
f8470165 (kx 2023-04-07 06:34:02 +0300 314)       b = next();
f8470165 (kx 2023-04-07 06:34:02 +0300 315)     }
f8470165 (kx 2023-04-07 06:34:02 +0300 316)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 317) }
f8470165 (kx 2023-04-07 06:34:02 +0300 318) 
f8470165 (kx 2023-04-07 06:34:02 +0300 319) 
f8470165 (kx 2023-04-07 06:34:02 +0300 320) /*
f8470165 (kx 2023-04-07 06:34:02 +0300 321)    jsmin - Copy the input to the output, deleting the characters which are
f8470165 (kx 2023-04-07 06:34:02 +0300 322)            insignificant to JavaScript. Comments will be removed. Tabs will be
f8470165 (kx 2023-04-07 06:34:02 +0300 323)            replaced with spaces. Carriage returns will be replaced with linefeeds.
f8470165 (kx 2023-04-07 06:34:02 +0300 324)            Most spaces and linefeeds will be removed.
f8470165 (kx 2023-04-07 06:34:02 +0300 325) */
f8470165 (kx 2023-04-07 06:34:02 +0300 326) 
f8470165 (kx 2023-04-07 06:34:02 +0300 327) static void
f8470165 (kx 2023-04-07 06:34:02 +0300 328) jsmin()
f8470165 (kx 2023-04-07 06:34:02 +0300 329) {
f8470165 (kx 2023-04-07 06:34:02 +0300 330)   if( peek() == 0xEF ) { get(); get(); get(); }
f8470165 (kx 2023-04-07 06:34:02 +0300 331)   a = '\n';
f8470165 (kx 2023-04-07 06:34:02 +0300 332)   action( 3 );
f8470165 (kx 2023-04-07 06:34:02 +0300 333) 
f8470165 (kx 2023-04-07 06:34:02 +0300 334)   while( a != EOF )
f8470165 (kx 2023-04-07 06:34:02 +0300 335)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 336)     switch( a )
f8470165 (kx 2023-04-07 06:34:02 +0300 337)     {
f8470165 (kx 2023-04-07 06:34:02 +0300 338)       case ' ':
f8470165 (kx 2023-04-07 06:34:02 +0300 339)         action(is_alpha_or_num(b) ? 1 : 2);
f8470165 (kx 2023-04-07 06:34:02 +0300 340)         break;
f8470165 (kx 2023-04-07 06:34:02 +0300 341)       case '\n':
f8470165 (kx 2023-04-07 06:34:02 +0300 342)         switch( b )
f8470165 (kx 2023-04-07 06:34:02 +0300 343)         {
f8470165 (kx 2023-04-07 06:34:02 +0300 344)           case '{': case '[': case '(':
f8470165 (kx 2023-04-07 06:34:02 +0300 345)           case '+': case '-': case '!':
f8470165 (kx 2023-04-07 06:34:02 +0300 346)           case '~':
f8470165 (kx 2023-04-07 06:34:02 +0300 347)             action( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300 348)             break;
f8470165 (kx 2023-04-07 06:34:02 +0300 349)           case ' ':
f8470165 (kx 2023-04-07 06:34:02 +0300 350)             action( 3 );
f8470165 (kx 2023-04-07 06:34:02 +0300 351)             break;
f8470165 (kx 2023-04-07 06:34:02 +0300 352)           default:
f8470165 (kx 2023-04-07 06:34:02 +0300 353)             action( is_alpha_or_num(b) ? 1 : 2 );
f8470165 (kx 2023-04-07 06:34:02 +0300 354)         }
f8470165 (kx 2023-04-07 06:34:02 +0300 355)         break;
f8470165 (kx 2023-04-07 06:34:02 +0300 356)       default:
f8470165 (kx 2023-04-07 06:34:02 +0300 357)         switch( b )
f8470165 (kx 2023-04-07 06:34:02 +0300 358)         {
f8470165 (kx 2023-04-07 06:34:02 +0300 359)           case ' ':
f8470165 (kx 2023-04-07 06:34:02 +0300 360)             action( is_alpha_or_num(a) ? 1 : 3 );
f8470165 (kx 2023-04-07 06:34:02 +0300 361)             break;
f8470165 (kx 2023-04-07 06:34:02 +0300 362)           case '\n':
f8470165 (kx 2023-04-07 06:34:02 +0300 363)             switch( a )
f8470165 (kx 2023-04-07 06:34:02 +0300 364)             {
f8470165 (kx 2023-04-07 06:34:02 +0300 365)               case '}':  case ']': case ')':
f8470165 (kx 2023-04-07 06:34:02 +0300 366)               case '+':  case '-': case '"':
f8470165 (kx 2023-04-07 06:34:02 +0300 367)               case '\'': case '`':
f8470165 (kx 2023-04-07 06:34:02 +0300 368)                 action( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300 369)                 break;
f8470165 (kx 2023-04-07 06:34:02 +0300 370)               default:
f8470165 (kx 2023-04-07 06:34:02 +0300 371)                 action( is_alpha_or_num(a) ? 1 : 3 );
f8470165 (kx 2023-04-07 06:34:02 +0300 372)             }
f8470165 (kx 2023-04-07 06:34:02 +0300 373)             break;
f8470165 (kx 2023-04-07 06:34:02 +0300 374)           default:
f8470165 (kx 2023-04-07 06:34:02 +0300 375)             action( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300 376)             break;
f8470165 (kx 2023-04-07 06:34:02 +0300 377)         }
f8470165 (kx 2023-04-07 06:34:02 +0300 378)     }
f8470165 (kx 2023-04-07 06:34:02 +0300 379)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 380)   /* lats carriage return */
f8470165 (kx 2023-04-07 06:34:02 +0300 381)   putc( '\n', ofile );
f8470165 (kx 2023-04-07 06:34:02 +0300 382) }
f8470165 (kx 2023-04-07 06:34:02 +0300 383) 
f8470165 (kx 2023-04-07 06:34:02 +0300 384) int is_file_exist( const char *filename )
f8470165 (kx 2023-04-07 06:34:02 +0300 385) {
f8470165 (kx 2023-04-07 06:34:02 +0300 386)   struct stat st;
f8470165 (kx 2023-04-07 06:34:02 +0300 387)   int result = stat( filename, &st );
f8470165 (kx 2023-04-07 06:34:02 +0300 388)   return result == 0;
f8470165 (kx 2023-04-07 06:34:02 +0300 389) }
f8470165 (kx 2023-04-07 06:34:02 +0300 390) 
f8470165 (kx 2023-04-07 06:34:02 +0300 391) static void
f8470165 (kx 2023-04-07 06:34:02 +0300 392) getargs( argc, argv )
f8470165 (kx 2023-04-07 06:34:02 +0300 393)   int   argc;
f8470165 (kx 2023-04-07 06:34:02 +0300 394)   char *argv[];
f8470165 (kx 2023-04-07 06:34:02 +0300 395) {
f8470165 (kx 2023-04-07 06:34:02 +0300 396)   int option       = 0;
f8470165 (kx 2023-04-07 06:34:02 +0300 397)   int option_index = 0;
f8470165 (kx 2023-04-07 06:34:02 +0300 398)   static struct option long_options[] =
f8470165 (kx 2023-04-07 06:34:02 +0300 399)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 400)     { "output", required_argument, 0, 'o' },
f8470165 (kx 2023-04-07 06:34:02 +0300 401)     { "help",         no_argument, 0, 'h' },
f8470165 (kx 2023-04-07 06:34:02 +0300 402)     { "version",      no_argument, 0, 'v' },
f8470165 (kx 2023-04-07 06:34:02 +0300 403)     { 0,                        0, 0,  0  },
f8470165 (kx 2023-04-07 06:34:02 +0300 404)   };
f8470165 (kx 2023-04-07 06:34:02 +0300 405) 
f8470165 (kx 2023-04-07 06:34:02 +0300 406)   opterr = 0;
f8470165 (kx 2023-04-07 06:34:02 +0300 407) 
f8470165 (kx 2023-04-07 06:34:02 +0300 408)   while( (option = getopt_long( argc, argv, "o:hv", long_options, &option_index )) != -1 )
f8470165 (kx 2023-04-07 06:34:02 +0300 409)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 410)     switch( option )
f8470165 (kx 2023-04-07 06:34:02 +0300 411)     {
f8470165 (kx 2023-04-07 06:34:02 +0300 412)       case 'o':
f8470165 (kx 2023-04-07 06:34:02 +0300 413)         ofname = optarg;
f8470165 (kx 2023-04-07 06:34:02 +0300 414)         break;
f8470165 (kx 2023-04-07 06:34:02 +0300 415)       case 'h':
f8470165 (kx 2023-04-07 06:34:02 +0300 416)         opt_usage   = 1;
f8470165 (kx 2023-04-07 06:34:02 +0300 417)         break;
f8470165 (kx 2023-04-07 06:34:02 +0300 418)       case 'v':
f8470165 (kx 2023-04-07 06:34:02 +0300 419)         opt_version = 1;
f8470165 (kx 2023-04-07 06:34:02 +0300 420)         break;
f8470165 (kx 2023-04-07 06:34:02 +0300 421)       case '?':
f8470165 (kx 2023-04-07 06:34:02 +0300 422)         {
f8470165 (kx 2023-04-07 06:34:02 +0300 423)           if( optopt == 'o' )
f8470165 (kx 2023-04-07 06:34:02 +0300 424)             fprintf( stderr,"\nERROR: %s: option '-%c' requires an argument\n\n", progname, optopt );
f8470165 (kx 2023-04-07 06:34:02 +0300 425)         }
f8470165 (kx 2023-04-07 06:34:02 +0300 426)       default:
f8470165 (kx 2023-04-07 06:34:02 +0300 427)         usage();
f8470165 (kx 2023-04-07 06:34:02 +0300 428)         break;
f8470165 (kx 2023-04-07 06:34:02 +0300 429)     }
f8470165 (kx 2023-04-07 06:34:02 +0300 430)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 431) 
f8470165 (kx 2023-04-07 06:34:02 +0300 432)   if( optind < argc )
f8470165 (kx 2023-04-07 06:34:02 +0300 433)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 434)     ifname = argv[optind++];
f8470165 (kx 2023-04-07 06:34:02 +0300 435)     if( optind < argc ) usage();
f8470165 (kx 2023-04-07 06:34:02 +0300 436)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 437) 
f8470165 (kx 2023-04-07 06:34:02 +0300 438)   if( opt_usage )   usage();
f8470165 (kx 2023-04-07 06:34:02 +0300 439)   if( opt_version ) version();
f8470165 (kx 2023-04-07 06:34:02 +0300 440)   if( opt_usage || ( ! ifname && ! ofname ) ) usage();
f8470165 (kx 2023-04-07 06:34:02 +0300 441) 
f8470165 (kx 2023-04-07 06:34:02 +0300 442)   if( ! ofname ) ofname = "-" ;
f8470165 (kx 2023-04-07 06:34:02 +0300 443)   if( ! ifname ) ifname = "-" ;
f8470165 (kx 2023-04-07 06:34:02 +0300 444) }
f8470165 (kx 2023-04-07 06:34:02 +0300 445) 
f8470165 (kx 2023-04-07 06:34:02 +0300 446) int main( int argc, char *argv[] )
f8470165 (kx 2023-04-07 06:34:02 +0300 447) {
f8470165 (kx 2023-04-07 06:34:02 +0300 448)   int use_stdin = 0, use_stdout = 0, use_tmpfile = 0;
f8470165 (kx 2023-04-07 06:34:02 +0300 449) 
f8470165 (kx 2023-04-07 06:34:02 +0300 450)   progname = rindex( argv[0], DIR_SEPARATOR ) + 1;
f8470165 (kx 2023-04-07 06:34:02 +0300 451)   getargs( argc, argv );
f8470165 (kx 2023-04-07 06:34:02 +0300 452) 
f8470165 (kx 2023-04-07 06:34:02 +0300 453) 
f8470165 (kx 2023-04-07 06:34:02 +0300 454)   if( ! strncmp( ifname, "-", 1 ) )
f8470165 (kx 2023-04-07 06:34:02 +0300 455)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 456)     ifile = stdin;
f8470165 (kx 2023-04-07 06:34:02 +0300 457)     use_stdin = 1;
f8470165 (kx 2023-04-07 06:34:02 +0300 458)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 459)   else
f8470165 (kx 2023-04-07 06:34:02 +0300 460)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 461)     ifile = fopen( ifname, "r" );
f8470165 (kx 2023-04-07 06:34:02 +0300 462)     if( ifile == NULL )
f8470165 (kx 2023-04-07 06:34:02 +0300 463)     {
f8470165 (kx 2023-04-07 06:34:02 +0300 464)       fprintf( stderr, "ERROR: Can't open '%s' file\n", ifname );
f8470165 (kx 2023-04-07 06:34:02 +0300 465)       exit( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300 466)     }
f8470165 (kx 2023-04-07 06:34:02 +0300 467)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 468) 
f8470165 (kx 2023-04-07 06:34:02 +0300 469)   if( ! strncmp( ofname, "-", 1 ) )
f8470165 (kx 2023-04-07 06:34:02 +0300 470)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 471)     ofile = stdout;
f8470165 (kx 2023-04-07 06:34:02 +0300 472)     use_stdout = 1;
f8470165 (kx 2023-04-07 06:34:02 +0300 473)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 474)   else
f8470165 (kx 2023-04-07 06:34:02 +0300 475)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 476)     if( is_file_exist( ofname ) )
f8470165 (kx 2023-04-07 06:34:02 +0300 477)     {
f8470165 (kx 2023-04-07 06:34:02 +0300 478)       /*
f8470165 (kx 2023-04-07 06:34:02 +0300 479)         use temporary file to presave file content
f8470165 (kx 2023-04-07 06:34:02 +0300 480)         in case when input and output the same file.
f8470165 (kx 2023-04-07 06:34:02 +0300 481)        */
f8470165 (kx 2023-04-07 06:34:02 +0300 482)       ofile = tmpfile();
f8470165 (kx 2023-04-07 06:34:02 +0300 483)       if( ofile == NULL )
f8470165 (kx 2023-04-07 06:34:02 +0300 484)       {
f8470165 (kx 2023-04-07 06:34:02 +0300 485)         fprintf( stderr, "ERROR: Can't open TEMPORARY file\n" );
f8470165 (kx 2023-04-07 06:34:02 +0300 486)         exit( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300 487)       }
f8470165 (kx 2023-04-07 06:34:02 +0300 488)       use_tmpfile = 1;
f8470165 (kx 2023-04-07 06:34:02 +0300 489)     }
f8470165 (kx 2023-04-07 06:34:02 +0300 490)     else
f8470165 (kx 2023-04-07 06:34:02 +0300 491)     {
f8470165 (kx 2023-04-07 06:34:02 +0300 492)       ofile = fopen( ofname, "w+" );
f8470165 (kx 2023-04-07 06:34:02 +0300 493)       if( ofile == NULL )
f8470165 (kx 2023-04-07 06:34:02 +0300 494)       {
f8470165 (kx 2023-04-07 06:34:02 +0300 495)         fprintf( stderr, "ERROR: Can't open '%s' file\n", ofname );
f8470165 (kx 2023-04-07 06:34:02 +0300 496)         exit( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300 497)       }
f8470165 (kx 2023-04-07 06:34:02 +0300 498)     }
f8470165 (kx 2023-04-07 06:34:02 +0300 499)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 500) 
f8470165 (kx 2023-04-07 06:34:02 +0300 501) 
f8470165 (kx 2023-04-07 06:34:02 +0300 502)   jsmin();
f8470165 (kx 2023-04-07 06:34:02 +0300 503) 
f8470165 (kx 2023-04-07 06:34:02 +0300 504) 
f8470165 (kx 2023-04-07 06:34:02 +0300 505)   if( use_tmpfile )
f8470165 (kx 2023-04-07 06:34:02 +0300 506)   {
f8470165 (kx 2023-04-07 06:34:02 +0300 507)     tmp = fopen( ofname, "w+" );
f8470165 (kx 2023-04-07 06:34:02 +0300 508)     if( tmp == NULL )
f8470165 (kx 2023-04-07 06:34:02 +0300 509)     {
f8470165 (kx 2023-04-07 06:34:02 +0300 510)       fprintf( stderr, "ERROR: Can't open '%s' file\n", ofname );
f8470165 (kx 2023-04-07 06:34:02 +0300 511)       exit( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300 512)     }
f8470165 (kx 2023-04-07 06:34:02 +0300 513)     if( !fseek( ofile, 0, SEEK_SET ) )
f8470165 (kx 2023-04-07 06:34:02 +0300 514)     {
f8470165 (kx 2023-04-07 06:34:02 +0300 515)       int c;
f8470165 (kx 2023-04-07 06:34:02 +0300 516)       while( (c = getc( ofile )) != EOF )
f8470165 (kx 2023-04-07 06:34:02 +0300 517)       {
f8470165 (kx 2023-04-07 06:34:02 +0300 518)         putc( c, tmp );
f8470165 (kx 2023-04-07 06:34:02 +0300 519)       }
f8470165 (kx 2023-04-07 06:34:02 +0300 520)       fclose( tmp );
f8470165 (kx 2023-04-07 06:34:02 +0300 521)     }
f8470165 (kx 2023-04-07 06:34:02 +0300 522)     else
f8470165 (kx 2023-04-07 06:34:02 +0300 523)     {
f8470165 (kx 2023-04-07 06:34:02 +0300 524)       fprintf( stderr, "ERROR: Can't seek to beginning of the '%s' file\n", ofname );
f8470165 (kx 2023-04-07 06:34:02 +0300 525)       fclose( tmp );
f8470165 (kx 2023-04-07 06:34:02 +0300 526)       exit( 1 );
f8470165 (kx 2023-04-07 06:34:02 +0300 527)     }
f8470165 (kx 2023-04-07 06:34:02 +0300 528)   }
f8470165 (kx 2023-04-07 06:34:02 +0300 529) 
f8470165 (kx 2023-04-07 06:34:02 +0300 530)   if( ! use_stdin )  { fclose( ifile ); ifile = NULL; }
f8470165 (kx 2023-04-07 06:34:02 +0300 531)   if( ! use_stdout ) { fclose( ofile ); ofile = NULL; }
f8470165 (kx 2023-04-07 06:34:02 +0300 532)   exit( 0 );
f8470165 (kx 2023-04-07 06:34:02 +0300 533) }