~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to main.c

  • Committer: Arnold D. Robbins
  • Date: 2015-04-05 08:20:41 UTC
  • mfrom: (408.12.66)
  • Revision ID: git-v1:4de12ef40f9ea9a0b715903cfe6da51b97eedb77
Merge branch 'master' into cmake

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 */
4
4
 
5
5
/* 
6
 
 * Copyright (C) 1986, 1988, 1989, 1991-2014 the Free Software Foundation, Inc.
 
6
 * Copyright (C) 1986, 1988, 1989, 1991-2015 the Free Software Foundation, Inc.
7
7
 * 
8
8
 * This file is part of GAWK, the GNU implementation of the
9
9
 * AWK Programming Language.
24
24
 */
25
25
 
26
26
/* FIX THIS BEFORE EVERY RELEASE: */
27
 
#define UPDATE_YEAR     2014
 
27
#define UPDATE_YEAR     2015
28
28
 
29
29
#include "awk.h"
30
30
#include "getopt.h"
142
142
 
143
143
static void add_preassign(enum assign_type type, char *val);
144
144
 
 
145
static void parse_args(int argc, char **argv);
 
146
static void set_locale_stuff(void);
 
147
static bool stopped_early = false;
 
148
 
145
149
int do_flags = false;
146
150
bool do_optimize = false;               /* apply default optimizations */
147
151
static int do_nostalgia = false;        /* provide a blast from the past */
148
152
static int do_binary = false;           /* hands off my data! */
149
153
static int do_version = false;          /* print version info */
 
154
static const char *locale = "";         /* default value to setlocale */
150
155
 
151
156
int use_lc_numeric = false;     /* obey locale for decimal point */
152
157
 
153
 
#if MBS_SUPPORT
154
158
int gawk_mb_cur_max;            /* MB_CUR_MAX value, see comment in main() */
155
 
#endif
156
159
 
157
160
FILE *output_fp;                /* default gawk output, can be redirected in the debugger */
158
161
bool output_is_tty = false;     /* control flushing of output */
186
189
        { "lint",               optional_argument,      NULL,   'L' },
187
190
        { "lint-old",           no_argument,            NULL,   't' },
188
191
        { "load",               required_argument,      NULL,   'l' },
 
192
#if defined(LOCALEDEBUG)
 
193
        { "locale",             required_argument,      NULL,   'Z' },
 
194
#endif
189
195
        { "non-decimal-data",   no_argument,            NULL,   'n' },
190
196
        { "nostalgia",          no_argument,            & do_nostalgia, 1 },
191
197
        { "optimize",           no_argument,            NULL,   'O' },
209
215
int
210
216
main(int argc, char **argv)
211
217
{
212
 
        /*
213
 
         * The + on the front tells GNU getopt not to rearrange argv.
214
 
         */
215
 
        const char *optlist = "+F:f:v:W;bcCd::D::e:E:ghi:l:L:nNo::Op::MPrStVY";
216
 
        bool stopped_early = false;
217
 
        int old_optind;
218
218
        int i;
219
 
        int c;
220
 
        char *scan, *src;
221
219
        char *extra_stack;
222
220
        int have_srcfile = 0;
223
221
        SRCFILE *s;
233
231
#endif /* HAVE_MTRACE */
234
232
#endif /* HAVE_MCHECK_H */
235
233
 
236
 
#if defined(LC_CTYPE)
237
 
        setlocale(LC_CTYPE, "");
238
 
#endif
239
 
#if defined(LC_COLLATE)
240
 
        setlocale(LC_COLLATE, "");
241
 
#endif
242
 
#if defined(LC_MESSAGES)
243
 
        setlocale(LC_MESSAGES, "");
244
 
#endif
245
 
#if defined(LC_NUMERIC) && defined(HAVE_LOCALE_H)
246
 
        /*
247
 
         * Force the issue here.  According to POSIX 2001, decimal
248
 
         * point is used for parsing source code and for command-line
249
 
         * assignments and the locale value for processing input,
250
 
         * number to string conversion, and printing output.
251
 
         *
252
 
         * 10/2005 --- see below also; we now only use the locale's
253
 
         * decimal point if do_posix in effect.
254
 
         *
255
 
         * 9/2007:
256
 
         * This is a mess. We need to get the locale's numeric info for
257
 
         * the thousands separator for the %'d flag.
258
 
         */
259
 
        setlocale(LC_NUMERIC, "");
260
 
        init_locale(& loc);
261
 
        setlocale(LC_NUMERIC, "C");
262
 
#endif
263
 
#if defined(LC_TIME)
264
 
        setlocale(LC_TIME, "");
265
 
#endif
266
 
 
267
 
#if MBS_SUPPORT
268
 
        /*
269
 
         * In glibc, MB_CUR_MAX is actually a function.  This value is
270
 
         * tested *a lot* in many speed-critical places in gawk. Caching
271
 
         * this value once makes a speed difference.
272
 
         */
273
 
        gawk_mb_cur_max = MB_CUR_MAX;
274
 
        /* Without MBS_SUPPORT, gawk_mb_cur_max is 1. */
275
 
 
276
 
        /* init the cache for checking bytes if they're characters */
277
 
        init_btowc_cache();
278
 
#endif
 
234
        myname = gawk_name(argv[0]);
 
235
        os_arg_fixup(&argc, &argv); /* emulate redirection, expand wildcards */
 
236
 
 
237
        if (argc < 2)
 
238
                usage(EXIT_FAILURE, stderr);
279
239
 
280
240
        (void) bindtextdomain(PACKAGE, LOCALEDIR);
281
241
        (void) textdomain(PACKAGE);
307
267
        (void) stackoverflow_install_handler(catchstackoverflow, extra_stack, STACK_SIZE);
308
268
#undef STACK_SIZE
309
269
 
310
 
        myname = gawk_name(argv[0]);
311
 
        os_arg_fixup(&argc, &argv); /* emulate redirection, expand wildcards */
312
 
 
313
 
        if (argc < 2)
314
 
                usage(EXIT_FAILURE, stderr);
315
 
 
316
270
        /* initialize the null string */
317
271
        Nnull_string = make_string("", 0);
318
272
 
327
281
 
328
282
        output_fp = stdout;
329
283
 
330
 
        /* we do error messages ourselves on invalid options */
331
 
        opterr = false;
332
 
 
333
 
        /* copy argv before getopt gets to it; used to restart the debugger */  
334
 
        save_argv(argc, argv);
335
 
 
336
284
        /* initialize global (main) execution context */
337
285
        push_context(new_context());
338
286
 
339
 
        /* option processing. ready, set, go! */
340
 
        for (optopt = 0, old_optind = 1;
341
 
             (c = getopt_long(argc, argv, optlist, optab, NULL)) != EOF;
342
 
             optopt = 0, old_optind = optind) {
343
 
                if (do_posix)
344
 
                        opterr = true;
345
 
 
346
 
                switch (c) {
347
 
                case 'F':
348
 
                        add_preassign(PRE_ASSIGN_FS, optarg);
349
 
                        break;
350
 
 
351
 
                case 'E':
352
 
                        disallow_var_assigns = true;
353
 
                        /* fall through */
354
 
                case 'f':
355
 
                        /*
356
 
                         * Allow multiple -f options.
357
 
                         * This makes function libraries real easy.
358
 
                         * Most of the magic is in the scanner.
359
 
                         *
360
 
                         * The following is to allow for whitespace at the end
361
 
                         * of a #! /bin/gawk line in an executable file
362
 
                         */
363
 
                        scan = optarg;
364
 
                        if (argv[optind-1] != optarg)
365
 
                                while (isspace((unsigned char) *scan))
366
 
                                        scan++;
367
 
                        src = (*scan == '\0' ? argv[optind++] : optarg);
368
 
                        (void) add_srcfile((src && src[0] == '-' && src[1] == '\0') ?
369
 
                                        SRC_STDIN : SRC_FILE,
370
 
                                        src, srcfiles, NULL, NULL);
371
 
 
372
 
                        break;
373
 
 
374
 
                case 'v':
375
 
                        add_preassign(PRE_ASSIGN, optarg);
376
 
                        break;
377
 
 
378
 
                case 'b':
379
 
                        do_binary = true;
380
 
                        break;
381
 
 
382
 
                case 'c':
383
 
                        do_flags |= DO_TRADITIONAL;
384
 
                        break;
385
 
 
386
 
                case 'C':
387
 
                        copyleft();
388
 
                        break;
389
 
 
390
 
                case 'd':
391
 
                        do_flags |= DO_DUMP_VARS;
392
 
                        if (optarg != NULL && optarg[0] != '\0')
393
 
                                varfile = optarg;
394
 
                        break;
395
 
 
396
 
                case 'D':
397
 
                        do_flags |= DO_DEBUG;
398
 
                        if (optarg != NULL && optarg[0] != '\0')
399
 
                                command_file = optarg;
400
 
                        break;
401
 
 
402
 
                case 'e':
403
 
                        if (optarg[0] == '\0')
404
 
                                warning(_("empty argument to `-e/--source' ignored"));
405
 
                        else
406
 
                                (void) add_srcfile(SRC_CMDLINE, optarg, srcfiles, NULL, NULL);
407
 
                        break;
408
 
 
409
 
                case 'g':
410
 
                        do_flags |= DO_INTL;
411
 
                        break;
412
 
 
413
 
                case 'h':
414
 
                        /* write usage to stdout, per GNU coding stds */
415
 
                        usage(EXIT_SUCCESS, stdout);
416
 
                        break;
417
 
 
418
 
                case 'i':
419
 
                        (void) add_srcfile(SRC_INC, optarg, srcfiles, NULL, NULL);
420
 
                        break;
421
 
 
422
 
                case 'l':
423
 
                        (void) add_srcfile(SRC_EXTLIB, optarg, srcfiles, NULL, NULL);
424
 
                        break;
425
 
 
426
 
#ifndef NO_LINT
427
 
                case 'L':
428
 
                        do_flags |= DO_LINT_ALL;
429
 
                        if (optarg != NULL) {
430
 
                                if (strcmp(optarg, "fatal") == 0)
431
 
                                        lintfunc = r_fatal;
432
 
                                else if (strcmp(optarg, "invalid") == 0) {
433
 
                                        do_flags &= ~DO_LINT_ALL;
434
 
                                        do_flags |= DO_LINT_INVALID;
435
 
                                }
436
 
                        }
437
 
                        break;
438
 
 
439
 
                case 't':
440
 
                        do_flags |= DO_LINT_OLD;
441
 
                        break;
442
 
#else
443
 
                case 'L':
444
 
                case 't':
445
 
                        break;
446
 
#endif
447
 
 
448
 
                case 'n':
449
 
                        do_flags |= DO_NON_DEC_DATA;
450
 
                        break;
451
 
 
452
 
                case 'N':
453
 
                        use_lc_numeric = true;
454
 
                        break;
455
 
 
456
 
                case 'O':
457
 
                        do_optimize = true;
458
 
                        break;
459
 
 
460
 
                case 'p':
461
 
                        do_flags |= DO_PROFILE;
462
 
                        /* fall through */
463
 
                case 'o':
464
 
                        do_flags |= DO_PRETTY_PRINT;
465
 
                        if (optarg != NULL)
466
 
                                set_prof_file(optarg);
467
 
                        else
468
 
                                set_prof_file(DEFAULT_PROFILE);
469
 
                        break;
470
 
 
471
 
                case 'M':
472
 
#ifdef HAVE_MPFR
473
 
                        do_flags |= DO_MPFR;
474
 
#else
475
 
                        warning(_("-M ignored: MPFR/GMP support not compiled in"));
476
 
#endif
477
 
                        break;
478
 
 
479
 
                case 'P':
480
 
                        do_flags |= DO_POSIX;
481
 
                        break;
482
 
 
483
 
                case 'r':
484
 
                        do_flags |= DO_INTERVALS;
485
 
                        break;
486
 
 
487
 
                case 'S':
488
 
                        do_flags |= DO_SANDBOX;
489
 
                        break;
490
 
 
491
 
                case 'V':
492
 
                        do_version = true;
493
 
                        break;
494
 
 
495
 
                case 'W':       /* gawk specific options - now in getopt_long */
496
 
                        fprintf(stderr, _("%s: option `-W %s' unrecognized, ignored\n"),
497
 
                                argv[0], optarg);
498
 
                        break;
499
 
 
500
 
                case 0:
501
 
                        /*
502
 
                         * getopt_long found an option that sets a variable
503
 
                         * instead of returning a letter. Do nothing, just
504
 
                         * cycle around for the next one.
505
 
                         */
506
 
                        break;
507
 
 
508
 
                case 'Y':
509
 
#if defined(YYDEBUG) || defined(GAWKDEBUG)
510
 
                        if (c == 'Y') {
511
 
                                yydebug = 2;
512
 
                                break;
513
 
                        }
514
 
#endif
515
 
                        /* if not debugging, fall through */
516
 
                case '?':
517
 
                default:
518
 
                        /*
519
 
                         * If not posix, an unrecognized option stops argument
520
 
                         * processing so that it can go into ARGV for the awk
521
 
                         * program to see. This makes use of ``#! /bin/gawk -f''
522
 
                         * easier.
523
 
                         *
524
 
                         * However, it's never simple. If optopt is set,
525
 
                         * an option that requires an argument didn't get the
526
 
                         * argument. We care because if opterr is 0, then
527
 
                         * getopt_long won't print the error message for us.
528
 
                         */
529
 
                        if (! do_posix
530
 
                            && (optopt == '\0' || strchr(optlist, optopt) == NULL)) {
531
 
                                /*
532
 
                                 * can't just do optind--. In case of an
533
 
                                 * option with >= 2 letters, getopt_long
534
 
                                 * won't have incremented optind.
535
 
                                 */
536
 
                                optind = old_optind;
537
 
                                stopped_early = true;
538
 
                                goto out;
539
 
                        } else if (optopt != '\0') {
540
 
                                /* Use POSIX required message format */
541
 
                                fprintf(stderr,
542
 
                                        _("%s: option requires an argument -- %c\n"),
543
 
                                        myname, optopt);
544
 
                                usage(EXIT_FAILURE, stderr);
545
 
                        }
546
 
                        /* else
547
 
                                let getopt print error message for us */
548
 
                        break;
549
 
                }
550
 
                if (c == 'E')   /* --exec ends option processing */
551
 
                        break;
552
 
        }
553
 
out:
 
287
        parse_args(argc, argv);
 
288
 
 
289
        set_locale_stuff();
 
290
 
 
291
        /*
 
292
         * In glibc, MB_CUR_MAX is actually a function.  This value is
 
293
         * tested *a lot* in many speed-critical places in gawk. Caching
 
294
         * this value once makes a speed difference.
 
295
         */
 
296
        gawk_mb_cur_max = MB_CUR_MAX;
 
297
 
 
298
        /* init the cache for checking bytes if they're characters */
 
299
        init_btowc_cache();
554
300
 
555
301
        if (do_nostalgia)
556
302
                nostalgia();
583
329
        if (do_lint && os_is_setuid())
584
330
                warning(_("running %s setuid root may be a security problem"), myname);
585
331
 
586
 
#if MBS_SUPPORT
587
332
        if (do_binary) {
588
333
                if (do_posix)
589
334
                        warning(_("`--posix' overrides `--characters-as-bytes'"));
593
338
                setlocale(LC_ALL, "C");
594
339
#endif
595
340
        }
596
 
#endif
597
341
 
598
342
        if (do_debug)   /* Need to register the debugger pre-exec hook before any other */
599
343
                init_debug();
734
478
         * data using the local decimal point.
735
479
         */
736
480
        if (use_lc_numeric)
737
 
                setlocale(LC_NUMERIC, "");
 
481
                setlocale(LC_NUMERIC, locale);
738
482
#endif
739
 
        
 
483
 
740
484
        init_io();
741
485
        output_fp = stdout;
742
486
 
1050
794
                        (*(vp->assign))();
1051
795
        }
1052
796
 
1053
 
        /* Set up deferred variables (loaded only when accessed). */
 
797
        /* Load PROCINFO and ENVIRON */
1054
798
        if (! do_traditional)
1055
 
                register_deferred_variable("PROCINFO", load_procinfo);
1056
 
        register_deferred_variable("ENVIRON", load_environ);
 
799
                load_procinfo();
 
800
        load_environ();
1057
801
}
1058
802
 
1059
803
/* path_environ --- put path variable into environment if not already there */
1066
810
        NODE *tmp;
1067
811
 
1068
812
        tmp = make_string(pname, strlen(pname));
1069
 
        if (! in_array(ENVIRON_node, tmp)) {
1070
 
                /*
1071
 
                 * On VMS, environ[] only holds a subset of what getenv() can
1072
 
                 * find, so look AWKPATH up before resorting to default path.
1073
 
                 */
1074
 
                val = getenv(pname);
1075
 
                if (val == NULL)
1076
 
                        val = dflt;
1077
 
                aptr = assoc_lookup(ENVIRON_node, tmp);
 
813
        /*
 
814
         * On VMS, environ[] only holds a subset of what getenv() can
 
815
         * find, so look AWKPATH up before resorting to default path.
 
816
         */
 
817
        val = getenv(pname);
 
818
        if (val == NULL || *val == '\0')
 
819
                val = dflt;
 
820
        aptr = assoc_lookup(ENVIRON_node, tmp);
 
821
        /*
 
822
         * If original value was the empty string, set it to
 
823
         * the default value.
 
824
         */
 
825
        if ((*aptr)->stlen == 0) {
1078
826
                unref(*aptr);
1079
827
                *aptr = make_string(val, strlen(val));
1080
828
        }
 
829
 
1081
830
        unref(tmp);
1082
831
}
1083
832
 
1124
873
        /*
1125
874
         * Put AWKPATH and AWKLIBPATH into ENVIRON if not already there.
1126
875
         * This allows querying it from within awk programs.
 
876
         *
 
877
         * October 2014:
 
878
         * If their values are "", override with the default values;
 
879
         * since 2.10 AWKPATH used default value if environment's
 
880
         * value was "".
1127
881
         */
1128
882
        path_environ("AWKPATH", defpath);
1129
883
        path_environ("AWKLIBPATH", deflibpath);
1369
1123
                        setlocale(LC_NUMERIC, "C");
1370
1124
                (void) force_number(it);
1371
1125
                if (do_posix)
1372
 
                        setlocale(LC_NUMERIC, "");
 
1126
                        setlocale(LC_NUMERIC, locale);
1373
1127
#endif /* LC_NUMERIC */
1374
1128
 
1375
1129
                /*
1633
1387
        }
1634
1388
        return -1;
1635
1389
}
 
1390
 
 
1391
/* parse_args --- do the getopt_long thing */
 
1392
 
 
1393
static void
 
1394
parse_args(int argc, char **argv)
 
1395
{
 
1396
        /*
 
1397
         * The + on the front tells GNU getopt not to rearrange argv.
 
1398
         */
 
1399
        const char *optlist = "+F:f:v:W;bcCd::D::e:E:ghi:l:L:nNo::Op::MPrStVYZ:";
 
1400
        int old_optind;
 
1401
        int c;
 
1402
        char *scan;
 
1403
        char *src;
 
1404
 
 
1405
        /* we do error messages ourselves on invalid options */
 
1406
        opterr = false;
 
1407
 
 
1408
        /* copy argv before getopt gets to it; used to restart the debugger */  
 
1409
        save_argv(argc, argv);
 
1410
 
 
1411
        /* option processing. ready, set, go! */
 
1412
        for (optopt = 0, old_optind = 1;
 
1413
             (c = getopt_long(argc, argv, optlist, optab, NULL)) != EOF;
 
1414
             optopt = 0, old_optind = optind) {
 
1415
                if (do_posix)
 
1416
                        opterr = true;
 
1417
 
 
1418
                switch (c) {
 
1419
                case 'F':
 
1420
                        add_preassign(PRE_ASSIGN_FS, optarg);
 
1421
                        break;
 
1422
 
 
1423
                case 'E':
 
1424
                        disallow_var_assigns = true;
 
1425
                        /* fall through */
 
1426
                case 'f':
 
1427
                        /*
 
1428
                         * Allow multiple -f options.
 
1429
                         * This makes function libraries real easy.
 
1430
                         * Most of the magic is in the scanner.
 
1431
                         *
 
1432
                         * The following is to allow for whitespace at the end
 
1433
                         * of a #! /bin/gawk line in an executable file
 
1434
                         */
 
1435
                        scan = optarg;
 
1436
                        if (argv[optind-1] != optarg)
 
1437
                                while (isspace((unsigned char) *scan))
 
1438
                                        scan++;
 
1439
                        src = (*scan == '\0' ? argv[optind++] : optarg);
 
1440
                        (void) add_srcfile((src && src[0] == '-' && src[1] == '\0') ?
 
1441
                                        SRC_STDIN : SRC_FILE,
 
1442
                                        src, srcfiles, NULL, NULL);
 
1443
 
 
1444
                        break;
 
1445
 
 
1446
                case 'v':
 
1447
                        add_preassign(PRE_ASSIGN, optarg);
 
1448
                        break;
 
1449
 
 
1450
                case 'b':
 
1451
                        do_binary = true;
 
1452
                        break;
 
1453
 
 
1454
                case 'c':
 
1455
                        do_flags |= DO_TRADITIONAL;
 
1456
                        break;
 
1457
 
 
1458
                case 'C':
 
1459
                        copyleft();
 
1460
                        break;
 
1461
 
 
1462
                case 'd':
 
1463
                        do_flags |= DO_DUMP_VARS;
 
1464
                        if (optarg != NULL && optarg[0] != '\0')
 
1465
                                varfile = optarg;
 
1466
                        break;
 
1467
 
 
1468
                case 'D':
 
1469
                        do_flags |= DO_DEBUG;
 
1470
                        if (optarg != NULL && optarg[0] != '\0')
 
1471
                                command_file = optarg;
 
1472
                        break;
 
1473
 
 
1474
                case 'e':
 
1475
                        if (optarg[0] == '\0')
 
1476
                                warning(_("empty argument to `-e/--source' ignored"));
 
1477
                        else
 
1478
                                (void) add_srcfile(SRC_CMDLINE, optarg, srcfiles, NULL, NULL);
 
1479
                        break;
 
1480
 
 
1481
                case 'g':
 
1482
                        do_flags |= DO_INTL;
 
1483
                        break;
 
1484
 
 
1485
                case 'h':
 
1486
                        /* write usage to stdout, per GNU coding stds */
 
1487
                        usage(EXIT_SUCCESS, stdout);
 
1488
                        break;
 
1489
 
 
1490
                case 'i':
 
1491
                        (void) add_srcfile(SRC_INC, optarg, srcfiles, NULL, NULL);
 
1492
                        break;
 
1493
 
 
1494
                case 'l':
 
1495
                        (void) add_srcfile(SRC_EXTLIB, optarg, srcfiles, NULL, NULL);
 
1496
                        break;
 
1497
 
 
1498
#ifndef NO_LINT
 
1499
                case 'L':
 
1500
                        do_flags |= DO_LINT_ALL;
 
1501
                        if (optarg != NULL) {
 
1502
                                if (strcmp(optarg, "fatal") == 0)
 
1503
                                        lintfunc = r_fatal;
 
1504
                                else if (strcmp(optarg, "invalid") == 0) {
 
1505
                                        do_flags &= ~DO_LINT_ALL;
 
1506
                                        do_flags |= DO_LINT_INVALID;
 
1507
                                }
 
1508
                        }
 
1509
                        break;
 
1510
 
 
1511
                case 't':
 
1512
                        do_flags |= DO_LINT_OLD;
 
1513
                        break;
 
1514
#else
 
1515
                case 'L':
 
1516
                case 't':
 
1517
                        break;
 
1518
#endif
 
1519
 
 
1520
                case 'n':
 
1521
                        do_flags |= DO_NON_DEC_DATA;
 
1522
                        break;
 
1523
 
 
1524
                case 'N':
 
1525
                        use_lc_numeric = true;
 
1526
                        break;
 
1527
 
 
1528
                case 'O':
 
1529
                        do_optimize = true;
 
1530
                        break;
 
1531
 
 
1532
                case 'p':
 
1533
                        do_flags |= DO_PROFILE;
 
1534
                        /* fall through */
 
1535
                case 'o':
 
1536
                        do_flags |= DO_PRETTY_PRINT;
 
1537
                        if (optarg != NULL)
 
1538
                                set_prof_file(optarg);
 
1539
                        else
 
1540
                                set_prof_file(DEFAULT_PROFILE);
 
1541
                        break;
 
1542
 
 
1543
                case 'M':
 
1544
#ifdef HAVE_MPFR
 
1545
                        do_flags |= DO_MPFR;
 
1546
#else
 
1547
                        warning(_("-M ignored: MPFR/GMP support not compiled in"));
 
1548
#endif
 
1549
                        break;
 
1550
 
 
1551
                case 'P':
 
1552
                        do_flags |= DO_POSIX;
 
1553
                        break;
 
1554
 
 
1555
                case 'r':
 
1556
                        do_flags |= DO_INTERVALS;
 
1557
                        break;
 
1558
 
 
1559
                case 'S':
 
1560
                        do_flags |= DO_SANDBOX;
 
1561
                        break;
 
1562
 
 
1563
                case 'V':
 
1564
                        do_version = true;
 
1565
                        break;
 
1566
 
 
1567
                case 'W':       /* gawk specific options - now in getopt_long */
 
1568
                        fprintf(stderr, _("%s: option `-W %s' unrecognized, ignored\n"),
 
1569
                                argv[0], optarg);
 
1570
                        break;
 
1571
 
 
1572
                case 0:
 
1573
                        /*
 
1574
                         * getopt_long found an option that sets a variable
 
1575
                         * instead of returning a letter. Do nothing, just
 
1576
                         * cycle around for the next one.
 
1577
                         */
 
1578
                        break;
 
1579
 
 
1580
                case 'Y':
 
1581
                case 'Z':
 
1582
#if defined(YYDEBUG) || defined(GAWKDEBUG)
 
1583
                        if (c == 'Y') {
 
1584
                                yydebug = 2;
 
1585
                                break;
 
1586
                        }
 
1587
#endif
 
1588
#if defined(LOCALEDEBUG)
 
1589
                        if (c == 'Z') {
 
1590
                                locale = optarg;
 
1591
                                break;
 
1592
                        }
 
1593
#endif
 
1594
                        /* if not debugging, fall through */
 
1595
                case '?':
 
1596
                default:
 
1597
                        /*
 
1598
                         * If not posix, an unrecognized option stops argument
 
1599
                         * processing so that it can go into ARGV for the awk
 
1600
                         * program to see. This makes use of ``#! /bin/gawk -f''
 
1601
                         * easier.
 
1602
                         *
 
1603
                         * However, it's never simple. If optopt is set,
 
1604
                         * an option that requires an argument didn't get the
 
1605
                         * argument. We care because if opterr is 0, then
 
1606
                         * getopt_long won't print the error message for us.
 
1607
                         */
 
1608
                        if (! do_posix
 
1609
                            && (optopt == '\0' || strchr(optlist, optopt) == NULL)) {
 
1610
                                /*
 
1611
                                 * can't just do optind--. In case of an
 
1612
                                 * option with >= 2 letters, getopt_long
 
1613
                                 * won't have incremented optind.
 
1614
                                 */
 
1615
                                optind = old_optind;
 
1616
                                stopped_early = true;
 
1617
                                goto out;
 
1618
                        } else if (optopt != '\0') {
 
1619
                                /* Use POSIX required message format */
 
1620
                                fprintf(stderr,
 
1621
                                        _("%s: option requires an argument -- %c\n"),
 
1622
                                        myname, optopt);
 
1623
                                usage(EXIT_FAILURE, stderr);
 
1624
                        }
 
1625
                        /* else
 
1626
                                let getopt print error message for us */
 
1627
                        break;
 
1628
                }
 
1629
                if (c == 'E')   /* --exec ends option processing */
 
1630
                        break;
 
1631
        }
 
1632
out:
 
1633
        return;
 
1634
}
 
1635
 
 
1636
/* set_locale_stuff --- setup the locale stuff */
 
1637
 
 
1638
static void
 
1639
set_locale_stuff(void)
 
1640
{
 
1641
#if defined(LC_CTYPE)
 
1642
        setlocale(LC_CTYPE, locale);
 
1643
#endif
 
1644
#if defined(LC_COLLATE)
 
1645
        setlocale(LC_COLLATE, locale);
 
1646
#endif
 
1647
#if defined(LC_MESSAGES)
 
1648
        setlocale(LC_MESSAGES, locale);
 
1649
#endif
 
1650
#if defined(LC_NUMERIC) && defined(HAVE_LOCALE_H)
 
1651
        /*
 
1652
         * Force the issue here.  According to POSIX 2001, decimal
 
1653
         * point is used for parsing source code and for command-line
 
1654
         * assignments and the locale value for processing input,
 
1655
         * number to string conversion, and printing output.
 
1656
         *
 
1657
         * 10/2005 --- see below also; we now only use the locale's
 
1658
         * decimal point if do_posix in effect.
 
1659
         *
 
1660
         * 9/2007:
 
1661
         * This is a mess. We need to get the locale's numeric info for
 
1662
         * the thousands separator for the %'d flag.
 
1663
         */
 
1664
        setlocale(LC_NUMERIC, locale);
 
1665
        init_locale(& loc);
 
1666
        setlocale(LC_NUMERIC, "C");
 
1667
#endif
 
1668
#if defined(LC_TIME)
 
1669
        setlocale(LC_TIME, locale);
 
1670
#endif
 
1671
}