Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom / options.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 /* $Id: options.c,v 3.28 1994/06/24 12:05:32 ceriel Exp $ */
6 /*      U S E R   O P T I O N - H A N D L I N G         */
7
8 #include        "lint.h"
9 #include        "botch_free.h"
10 #include        <alloc.h>
11 #include        "nofloat.h"
12 #include        "nopp.h"
13 #include        "idfsize.h"
14 #include        "nobitfield.h"
15 #include        "class.h"
16 #include        "macro.h"
17 #include        "idf.h"
18 #include        "arith.h"
19 #include        "sizes.h"
20 #include        "align.h"
21 #include        "use_tmp.h"
22 #include        "dataflow.h"
23 #include        "noRoption.h"
24 #include        "dbsymtab.h"
25
26 #ifndef NOPP
27 extern char **inctable;
28 extern int inc_pos;
29 extern int inc_max;
30 extern int inc_total;
31 int do_dependencies = 0;
32 char *dep_file = 0;
33
34 #endif /* NOPP */
35
36 char options[128];                      /* one for every char   */
37 #ifdef  LINT
38 char loptions[128];                     /* one for every char   */
39 #endif  /* LINT */
40
41 extern int idfsize;
42 extern int density;
43
44 static int txt2int();
45
46 do_option(text)
47         char *text;
48 {
49         register char opt;
50
51 next_option:                    /* to allow combined one-char options */
52         switch (opt = *text++)  {
53
54         case 0:                 /* to end the goto next_option loop */
55                 break;
56
57         default:
58 #ifndef LINT
59                 fatal("illegal option: %c", opt);
60 #else   /* LINT */
61                 warning("illegal option: %c", opt);
62 #endif  /* LINT */
63                 break;
64
65         case '-':
66                 options[*text++] = 1;   /* flags, debug options etc.    */
67                 goto next_option;
68
69 #ifndef LINT
70 #ifdef  DATAFLOW
71         case 'd':
72 #endif  /* DATAFLOW */
73         case 'p':                       /* procentry/procexit */
74         case 'L' :                      /* no fil/lin */
75         case 'n':                       /* use no registers */
76         case 'w':                       /* no warnings will be given */
77                 options[opt] = 1;
78                 goto next_option;
79 #endif  /* LINT */
80
81 #ifdef  LINT
82         case 'h':       /* heuristic tests */
83         case 'v':       /* no complaints about unused arguments */
84         case 'a':       /* check long->int int->long conversions */
85         case 'b':       /* don't report unreachable break-statements */
86         case 'x':       /* complain about unused extern declared variables */
87         case 'u':       /* no "used but not defined"; for pass 2 */
88         case 'L':       /* lintlibrary */
89                 loptions[opt] = 1;
90                 goto next_option;
91 #endif  /* LINT */
92
93 #ifndef LINT
94 #ifndef NOPP
95         case 'A' :      /* Amake dependency generation */
96                 do_dependencies = 1;
97                 if (*text) {
98                         dep_file = text;
99                 }
100                 break;
101         case 'i':
102         case 'm':
103                 options[opt] = 1;
104                 break;
105 #endif /* NOPP */
106 #endif /* LINT */
107 #ifdef DBSYMTAB
108         case 'g':       /* symbol table for debugger */
109                 options['g'] = 1;
110                 options['n'] = 1;
111                 break;
112 #endif /* DBSYMTAB */
113
114         case 'R':                       /* strict version */
115 #ifndef NOROPTION
116                 options[opt] = 1;
117 #else   /* NOROPTION */
118                 warning("-R option not implemented");
119 #endif  /* NOROPTION */
120                 goto next_option;
121
122 #ifdef  ___XXX___
123 deleted, is now a debug-flag
124         case 'C' :      /* E option + comment output            */
125 #ifndef NOPP
126                 options['E'] = 1;
127                 warning("-C: comment is not output");
128 #else /* NOPP */
129                 warning("-C option ignored");
130 #endif  /* NOPP */
131                 break;
132 #endif  /* ___XXX___ */
133
134         case 'D' :      {       /* -Dname :     predefine name          */
135 #ifndef NOPP
136                 register char *cp = text, *name, *mactext;
137
138                 if (class(*cp) != STIDF)        {
139                         error("identifier missing in -D%s", text);
140                         break;
141                 }
142
143                 name = cp;
144
145                 while (*cp && in_idf(*cp)) {
146                         ++cp;
147                 }
148
149                 if (!*cp) {                     /* -Dname */
150                         mactext = "1";
151                 }
152                 else
153                 if (*cp == '=') {               /* -Dname=text  */
154                         *cp++ = '\0';           /* end of name  */
155                         mactext = cp;
156                 }
157                 else    {                       /* -Dname?? */
158                         error("malformed option -D%s", text);
159                         break;
160                 }
161
162                 macro_def(str2idf(name), mactext, -1, strlen(mactext),
163                         NOFLAG);
164 #else /* NOPP */
165                 warning("-D option ignored");
166 #endif /* NOPP */
167                 break;
168         }
169
170 #ifdef ___XXX___
171 deleted, is now a debug-flag
172         case 'E' :      /* run preprocessor only, with #<int>   */
173 #ifndef NOPP
174                 options['E'] = 1;
175 #else /* NOPP */
176                 warning("-E option ignored");
177 #endif /* NOPP */
178                 break;
179 #endif /* ___XXX___ */
180
181         case 'I' :      /* -Ipath : insert "path" into include list     */
182 #ifndef NOPP
183                 if (*text)      {
184                         int i;
185                         register char *new = text;
186
187                         if (++inc_total > inc_max) {
188                                 inctable = (char **)
189                                   Realloc((char *) inctable,(inc_max+=10)*sizeof(char *));
190                         }
191
192                         for (i = inc_pos++; i < inc_total; i++) {
193                                 char *tmp = inctable[i];
194
195                                 inctable[i] = new;
196                                 new = tmp;
197                         }
198                 }
199                 else inctable[inc_pos] = 0;
200 #else /* NOPP */
201                 warning("-I option ignored");
202 #endif /* NOPP */
203                 break;
204
205         case 'M':       /* maximum identifier length */
206                 idfsize = txt2int(&text);
207                 if (*text || idfsize <= 0)
208                         fatal("malformed -M option");
209                 if (idfsize > IDFSIZE)
210                         fatal("maximum identifier length is %d", IDFSIZE);
211                 break;
212
213 #ifdef ___XXX___
214 deleted, is now a debug-flag
215         case 'P' :      /* run preprocessor stand-alone, without #'s    */
216 #ifndef NOPP
217                 options['E'] = 1;
218                 options['P'] = 1;
219 #else /* NOPP */
220                 warning("-P option ignored");
221 #endif /* NOPP */
222                 break;
223 #endif /* ___XXX___ */
224
225 #ifdef  LINT
226         case 'S' : {            /* -Sint :      static scope number for lint */
227                 extern int stat_number;
228                 stat_number = txt2int(&text);
229                 break;
230         }
231 #endif  /* LINT */
232
233         case 'T' : {
234 #ifdef USE_TMP
235                 extern char *C_tmpdir;
236                 if (*text)
237                         C_tmpdir = text;
238                 else
239                         C_tmpdir = ".";
240 #else /* USE_TMP */
241                 warning("-T option ignored");
242 #endif /* USE_TMP */
243                 break;
244         }
245
246         case 'U' :      {       /* -Uname :     undefine predefined     */
247 #ifndef NOPP
248                 register struct idf *idef;
249
250                 if (*text)      {
251                         if ((idef = str2idf(text))->id_macro) {
252                                 free_macro(idef->id_macro);
253                                 idef->id_macro = (struct macro *) 0;
254                         }
255                 }
256 #else /* NOPP */
257                 warning("-U option ignored");
258 #endif /* NOPP */
259                 break;
260         }
261
262 #ifndef LINT
263         case 'V' :      /* set object sizes and alignment requirements  */
264 #ifdef NOCROSS
265                 warning("-V option ignored");
266                 break;
267 #else /* NOCROSS */
268         {
269                 register arith sz, algn;
270                 char c;
271
272                 while (c = *text++)     {
273                         sz = txt2int(&text);
274                         algn = 0;
275                         if (*text == '.')       {
276                                 text++;
277                                 algn = txt2int(&text);
278                         }
279                         switch (c)      {
280                         case 's':       /* short        */
281                                 if (sz != (arith)0)
282                                         short_size = sz;
283                                 if (algn != 0)
284                                         short_align = algn;
285                                 break;
286                         case 'w':       /* word         */
287                                 if (sz != (arith)0)
288                                         dword_size = (word_size = sz) << 1;
289                                 if (algn != 0)
290                                         word_align = algn;
291                                 break;
292                         case 'i':       /* int          */
293                                 if (sz != (arith)0)
294                                         int_size = sz;
295                                 if (algn != 0)
296                                         int_align = algn;
297                                 break;
298                         case 'l':       /* long         */
299                                 if (sz != (arith)0)
300                                         long_size = sz;
301                                 if (algn != 0)
302                                         long_align = algn;
303                                 break;
304                         case 'f':       /* float        */
305 #ifndef NOFLOAT
306                                 if (sz != (arith)0)
307                                         float_size = sz;
308                                 if (algn != 0)
309                                         float_align = algn;
310 #endif /* NOFLOAT */
311                                 break;
312                         case 'd':       /* double       */
313 #ifndef NOFLOAT
314                                 if (sz != (arith)0)
315                                         double_size = sz;
316                                 if (algn != 0)
317                                         double_align = algn;
318 #endif /* NOFLOAT */
319                                 break;
320                         case 'p':       /* pointer      */
321                                 if (sz != (arith)0)
322                                         pointer_size = sz;
323                                 if (algn != 0)
324                                         pointer_align = algn;
325                                 break;
326                         case 'r':       /* adjust bitfields right       */
327 #ifndef NOBITFIELD
328                                 options['r'] = 1;
329 #else /* NOBITFIELD */
330                                 warning("bitfields are not implemented");
331 #endif /* NOBITFIELD */
332                                 break;
333                         case 'S':       /* initial struct alignment     */
334                                 if (sz != (arith)0)
335                                         struct_align = sz;
336                                 break;
337                         case 'U':       /* initial union alignment      */
338                                 if (sz != (arith)0)
339                                         union_align = sz;
340                                 break;
341                         default:
342                                 error("-V: bad type indicator %c\n", c);
343                         }
344                 }
345                 break;
346         }
347 #endif /* NOCROSS */
348         case 'S':
349                 density = txt2int(&text);
350                 break;
351 #endif  /* LINT */
352         }
353 }
354
355 static int
356 txt2int(tp)
357         register char **tp;
358 {
359         /*      the integer pointed to by *tp is read, while increasing
360                 *tp; the resulting value is yielded.
361         */
362         register int val = 0, ch;
363
364         while (ch = **tp, ch >= '0' && ch <= '9')       {
365                 val = val * 10 + ch - '0';
366                 (*tp)++;
367         }
368         return val;
369 }