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