Git init
[external/mawk.git] / init.c
1
2 /********************************************
3 init.c
4 copyright 1991, Michael D. Brennan
5
6 This is a source file for mawk, an implementation of
7 the AWK programming language.
8
9 Mawk is distributed without warranty under the terms of
10 the GNU General Public License, version 2, 1991.
11 ********************************************/
12
13
14 /* $Log: init.c,v $
15  * Revision 1.11  1995/08/20  17:35:21  mike
16  * include <stdlib.h> for MSC, needed for environ decl
17  *
18  * Revision 1.10  1995/06/09  22:51:50  mike
19  * silently exit(0) if no program
20  *
21  * Revision 1.9  1995/06/06  00:18:30  mike
22  * change mawk_exit(1) to mawk_exit(2)
23  *
24  * Revision 1.8  1994/12/14  14:40:34  mike
25  * -Wi option
26  *
27  * Revision 1.7  1994/12/11  22:43:20  mike
28  * don't assume **environ is writable
29  *
30  * Revision 1.6  1994/12/11  22:14:16  mike
31  * remove THINK_C #defines.  Not a political statement, just no indication
32  * that anyone ever used it.
33  *
34  * Revision 1.5  1994/10/08  19:15:45  mike
35  * remove SM_DOS
36  *
37  * Revision 1.4  1994/03/11  02:23:49  mike
38  * -We option
39  *
40  * Revision 1.3  1993/07/17  00:45:14  mike
41  * indent
42  *
43  * Revision 1.2  1993/07/04  12:52:00  mike
44  * start on autoconfig changes
45  *
46  * Revision 5.5  1993/01/07  02:50:33  mike
47  * relative vs absolute code
48  *
49  * Revision 5.4  1992/12/24  01:58:19  mike
50  * 1.1.2d changes for MsDOS
51  *
52  * Revision 5.3  1992/07/10  16:17:10  brennan
53  * MsDOS: remove NO_BINMODE macro
54  *
55  * Revision 5.2  1992/01/09  08:46:14  brennan
56  * small change for MSC
57  *
58  * Revision 5.1  91/12/05  07:56:07  brennan
59  * 1.1 pre-release
60  *
61 */
62
63
64 /* init.c */
65 #include "mawk.h"
66 #include "code.h"
67 #include "memory.h"
68 #include "symtype.h"
69 #include "init.h"
70 #include "bi_vars.h"
71 #include "field.h"
72 #include <stdlib.h>
73
74 #ifdef MSDOS
75 #include <fcntl.h>
76 #ifdef MSDOS_MSC
77 #include <stdlib.h>
78 #endif
79 #endif
80
81 static void PROTO(process_cmdline, (int, char **)) ;
82 static void PROTO(set_ARGV, (int, char **, int)) ;
83 static void PROTO(bad_option, (char *)) ;
84 static void PROTO(no_program, (void)) ;
85
86 extern void PROTO(print_version, (void)) ;
87 extern int PROTO(is_cmdline_assign, (char *)) ;
88
89 #if  MSDOS
90 void PROTO(stdout_init, (void)) ;
91 #if  HAVE_REARGV
92 void PROTO(reargv, (int *, char ***)) ;
93 #endif
94 #endif
95
96 char *progname ;
97 short interactive_flag = 0 ;
98
99 #ifndef  SET_PROGNAME
100 #define  SET_PROGNAME() \
101    {char *p = strrchr(argv[0],'/') ;\
102     progname = p ? p+1 : argv[0] ; }
103 #endif
104
105 void
106 initialize(argc, argv)
107 int argc ; char **argv ;
108 {
109
110    SET_PROGNAME() ;
111
112    bi_vars_init() ;              /* load the builtin variables */
113    bi_funct_init() ;             /* load the builtin functions */
114    kw_init() ;                   /* load the keywords */
115    field_init() ;
116
117 #if   MSDOS
118    {
119       char *p = getenv("MAWKBINMODE") ;
120
121       if (p)  set_binmode(atoi(p)) ;
122    }
123 #endif
124
125
126    process_cmdline(argc, argv) ;
127
128    code_init() ;
129    fpe_init() ;
130    set_stderr() ;
131
132 #if  MSDOS
133    stdout_init() ;
134 #endif
135 }
136
137 int dump_code_flag ;             /* if on dump internal code */
138 short posix_space_flag ;
139
140 #ifdef   DEBUG
141 int dump_RE ;                    /* if on dump compiled REs  */
142 #endif
143
144
145 static void
146 bad_option(s)
147    char *s ;
148 {
149    errmsg(0, "not an option: %s", s) ; mawk_exit(2) ; 
150 }
151
152 static void
153 no_program()
154 {
155    mawk_exit(0) ;
156 }
157
158 static void
159 process_cmdline(argc, argv)
160    int argc ;
161    char **argv ;
162 {
163    int i, nextarg ;
164    char *optarg ;
165    PFILE dummy ;                 /* starts linked list of filenames */
166    PFILE *tail = &dummy ;
167
168    for (i = 1; i < argc && argv[i][0] == '-'; i = nextarg)
169    {
170       if (argv[i][1] == 0)      /* -  alone */
171       {
172          if (!pfile_name) no_program() ;
173          break ;                 /* the for loop */
174       }
175       /* safe to look at argv[i][2] */
176
177       if (argv[i][2] == 0)
178       {
179          if (i == argc - 1 && argv[i][1] != '-')
180          {
181             if (strchr("WFvf", argv[i][1]))
182             {
183                errmsg(0, "option %s lacks argument", argv[i]) ;
184                mawk_exit(2) ;
185             }
186             bad_option(argv[i]) ;
187          }
188
189          optarg = argv[i + 1] ;
190          nextarg = i + 2 ;
191       }
192       else  /* argument glued to option */
193       {
194          optarg = &argv[i][2] ;
195          nextarg = i + 1 ;
196       }
197
198       switch (argv[i][1])
199       {
200          case 'W':
201
202             if (optarg[0] >= 'a' && optarg[0] <= 'z')
203                optarg[0] += 'A' - 'a' ;
204             if (optarg[0] == 'V')  print_version() ;
205             else if (optarg[0] == 'D')
206             {
207                dump_code_flag = 1 ;
208             }
209             else if (optarg[0] == 'S')
210             {
211                char *p = strchr(optarg, '=') ;
212                int x = p ? atoi(p + 1) : 0 ;
213
214                if (x > SPRINTF_SZ)
215                {
216                   sprintf_buff = (char *) zmalloc(x) ;
217                   sprintf_limit = sprintf_buff + x ;
218                }
219             }
220 #if  MSDOS
221             else if (optarg[0] == 'B')
222             {
223                char *p = strchr(optarg, '=') ;
224                int x = p ? atoi(p + 1) : 0 ;
225
226                set_binmode(x) ;
227             }
228 #endif
229             else if (optarg[0] == 'P')
230             {
231                posix_space_flag = 1 ;
232             }
233             else if (optarg[0] == 'E')
234             {
235                if ( pfile_name )
236                {
237                   errmsg(0, "-W exec is incompatible with -f") ;
238                   mawk_exit(2) ;
239                }
240                else if ( nextarg == argc ) no_program() ;
241
242                pfile_name = argv[nextarg] ;
243                i = nextarg + 1 ;
244                goto no_more_opts ;
245             }
246             else if (optarg[0] == 'I')
247             {
248                interactive_flag = 1 ;
249                setbuf(stdout,(char*)0) ;
250             }
251             else  errmsg(0, "vacuous option: -W %s", optarg) ;
252
253
254             break ;
255
256          case 'v':
257             if (!is_cmdline_assign(optarg))
258             {
259                errmsg(0, "improper assignment: -v %s", optarg) ;
260                mawk_exit(2) ;
261             }
262             break ;
263
264          case 'F':
265
266             rm_escape(optarg) ;  /* recognize escape sequences */
267             cell_destroy(FS) ;
268             FS->type = C_STRING ;
269             FS->ptr = (PTR) new_STRING(optarg) ;
270             cast_for_split(cellcpy(&fs_shadow, FS)) ;
271             break ;
272
273          case '-':
274             if (argv[i][2] != 0)  bad_option(argv[i]) ;
275             i++ ;
276             goto no_more_opts ;
277
278          case 'f':
279             /* first file goes in pfile_name ; any more go
280                on a list */
281             if (!pfile_name)  pfile_name = optarg ;
282             else
283             {
284                tail = tail->link = ZMALLOC(PFILE) ;
285                tail->fname = optarg ;
286             }
287             break ;
288
289          default:
290             bad_option(argv[i]) ;
291       }
292    }
293
294  no_more_opts:
295
296    tail->link = (PFILE *) 0 ;
297    pfile_list = dummy.link ;
298
299    if (pfile_name)
300    {
301       set_ARGV(argc, argv, i) ;
302       scan_init((char *) 0) ;
303    }
304    else  /* program on command line */
305    {
306       if (i == argc)  no_program() ;
307       set_ARGV(argc, argv, i + 1) ;
308
309 #if  MSDOS && ! HAVE_REARGV     /* reversed quotes */
310       {
311          char *p ;
312
313          for (p = argv[i]; *p; p++)
314             if (*p == '\'')  *p = '\"' ;
315       }
316 #endif
317       scan_init(argv[i]) ;
318 /* #endif  */
319    }
320 }
321
322
323 static void
324 set_ARGV(argc, argv, i)
325 int argc ; char **argv ;
326    int i ;                       /* argv[i] = ARGV[i] */
327 {
328    SYMTAB *st_p ;
329    CELL argi ;
330    register CELL *cp ;
331
332    st_p = insert("ARGV") ;
333    st_p->type = ST_ARRAY ;
334    Argv = st_p->stval.array = new_ARRAY() ;
335    argi.type = C_DOUBLE ;
336    argi.dval = 0.0 ;
337    cp = array_find(st_p->stval.array, &argi, CREATE) ;
338    cp->type = C_STRING ;
339    cp->ptr = (PTR) new_STRING(progname) ;
340
341    /* ARGV[0] is set, do the rest
342      The type of ARGV[1] ... should be C_MBSTRN
343      because the user might enter numbers from the command line */
344
345    for (argi.dval = 1.0; i < argc; i++, argi.dval += 1.0)
346    {
347       cp = array_find(st_p->stval.array, &argi, CREATE) ;
348       cp->type = C_MBSTRN ;
349       cp->ptr = (PTR) new_STRING(argv[i]) ;
350    }
351    ARGC->type = C_DOUBLE ;
352    ARGC->dval = argi.dval ;
353 }
354
355
356 /*----- ENVIRON ----------*/
357
358 void
359 load_environ(ENV)
360    ARRAY ENV ;
361 {
362    CELL c ;
363 #ifndef  MSDOS_MSC              /* MSC declares it near */
364    extern char **environ ;
365 #endif
366    register char **p = environ ; /* walks environ */
367    char *s ;                     /* looks for the '=' */
368    CELL *cp ;                    /* pts at ENV[&c] */
369
370    c.type = C_STRING ;
371
372    while (*p)
373    {
374       if ((s = strchr(*p, '=')))        /* shouldn't fail */
375       {
376          int len = s - *p ;
377          c.ptr = (PTR) new_STRING0(len) ;
378          memcpy(string(&c)->str, *p, len) ;
379          s++ ;
380
381          cp = array_find(ENV, &c, CREATE) ;
382          cp->type = C_MBSTRN ;
383          cp->ptr = (PTR) new_STRING(s) ;
384
385          free_STRING(string(&c)) ;
386       }
387       p++ ;
388    }
389 }