1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 * escmain.c -- main routine for esc, the eversholt compiler 27 * 28 * argument processing and the general flow through all the other 29 * modules is driven by this file. 30 */ 31 32 #pragma ident "%Z%%M% %I% %E% SMI" 33 34 #include <stdio.h> 35 #include <string.h> 36 #ifdef sun 37 #include <stdlib.h> 38 #else 39 #include <getopt.h> 40 #endif /* sun */ 41 #include "out.h" 42 #include "stats.h" 43 #include "alloc.h" 44 #include "stable.h" 45 #include "literals.h" 46 #include "lut.h" 47 #include "esclex.h" 48 #include "eftwrite.h" 49 #include "ptree.h" 50 #include "tree.h" 51 #include "check.h" 52 #include "version.h" 53 54 /* stuff exported by yacc-generated parsers */ 55 extern void yyparse(void); 56 extern int yydebug; 57 58 /* 59 * This external definition has to be here. If we put it in literals.h 60 * lint complains about the declaration not being used within the block 61 * when compiling literals.c. 62 */ 63 extern void literals_init(void); 64 65 static const char *Usage = 66 "[-SYdghpqvy] [-Dname[=def]] [-I dir] [-Uname] [-o outfile] esc-files..."; 67 static const char *Help = 68 "\tinput files are run through cpp and concatenated.\n" 69 "\t-D name[=def] Pass to cpp\n" 70 "\t-I dir Pass to cpp\n" 71 "\t-S Print stats for compiler memory usage, etc.\n" 72 "\t-U name Pass to cpp\n" 73 "\t-Y Enable parser debug output\n" 74 "\t-d Enable general debug output\n" 75 "\t-g Print generated iterators (use with -p)\n" 76 "\t-h Print this help message\n" 77 "\t-o outfile Emit compiled EFT to \"outfile\"\n" 78 "\t-p Print complete parse tree\n" 79 "\t-q Quiet mode: suppress warnings\n" 80 "\t-v Enable verbose output\n" 81 "\t-y Enable lexer debug output"; 82 83 int Debug; 84 int Verbose; 85 int Warn = 1; /* the esc compiler should issue language warnings */ 86 87 extern int Pchildgen; /* flag to ptree for printing generated iterators */ 88 89 #define MAXARGS 8192 90 char Args[MAXARGS]; 91 92 #define MAXCPPARGS 4000 93 static char Cppargs[MAXCPPARGS]; 94 95 int 96 main(int argc, char *argv[]) 97 { 98 char flagbuf[] = " -D"; 99 char **av; 100 int c; 101 int stats = 0; 102 int lexecho = 0; 103 const char *outfile = NULL; 104 int count; 105 int i; 106 int pflag = 0; 107 108 alloc_init(); 109 out_init(argv[0]); 110 stats_init(1); /* extended stats always enabled for esc */ 111 stable_init(0); 112 literals_init(); 113 lut_init(); 114 tree_init(); 115 eftwrite_init(); 116 117 /* built a best effort summary of args for eftwrite() */ 118 count = 0; 119 for (i = 1; i < argc; i++) { 120 char *ptr = argv[i]; 121 122 if (count < MAXARGS - 1) 123 Args[count++] = ' '; 124 125 while (count < MAXARGS - 1 && *ptr) 126 Args[count++] = *ptr++; 127 128 } 129 Args[count] = '\0'; 130 131 132 133 while ((c = getopt(argc, argv, "D:I:SU:Ydgho:pqvy")) != EOF) { 134 switch (c) { 135 case 'D': 136 case 'I': 137 case 'U': 138 if (strlen(optarg) + strlen(Cppargs) + 4 >= MAXCPPARGS) 139 out(O_DIE, "cpp args too long (max %d bytes)", 140 MAXCPPARGS); 141 flagbuf[2] = c; 142 (void) strcat(Cppargs, flagbuf); 143 (void) strcat(Cppargs, optarg); 144 break; 145 146 case 'S': 147 stats++; 148 break; 149 150 case 'Y': 151 yydebug++; 152 break; 153 154 case 'd': 155 Debug++; 156 break; 157 158 case 'g': 159 Pchildgen++; 160 break; 161 162 case 'h': 163 case '?': 164 out(O_PROG, "eversholt compiler version %d.%d", 165 VERSION_MAJOR, VERSION_MINOR); 166 out(O_DIE|O_USAGE, "%s\n%s", Usage, Help); 167 /*NOTREACHED*/ 168 169 case 'o': 170 outfile = optarg; 171 break; 172 173 case 'p': 174 pflag++; 175 break; 176 177 case 'q': 178 Warn = 0; 179 break; 180 181 case 'v': 182 Verbose++; 183 break; 184 185 case 'y': 186 lexecho++; 187 break; 188 189 default: 190 out(O_DIE|O_USAGE, Usage); 191 /*NOTREACHED*/ 192 } 193 } 194 195 out(O_PROG|O_VERB, "eversholt compiler version %d.%d", 196 VERSION_MAJOR, VERSION_MINOR); 197 198 argc -= optind; 199 av = &argv[optind]; 200 201 if (argc < 1) { 202 out(O_ERR, "no esc source files given"); 203 out(O_DIE|O_USAGE, Usage); 204 /*NOTREACHED*/ 205 } 206 207 lex_init(av, Cppargs, lexecho); 208 check_init(); 209 yyparse(); 210 (void) lex_fini(); 211 212 tree_report(); 213 214 if (count = out_errcount()) 215 out(O_DIE, "%d language error%s encountered, exiting.", 216 OUTS(count)); 217 218 if (outfile) 219 eftwrite(outfile); 220 221 if (pflag) 222 ptree_name_iter(O_OK, tree_root(NULL)); 223 224 if (stats) { 225 out(O_OK, "Stats:"); 226 stats_publish(); 227 } 228 229 out_exit(0); 230 /*NOTREACHED*/ 231 return (0); 232 } 233