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