~dexter/parrot-pkg/maverick

« back to all changes in this revision

Viewing changes to frontend/parrot/main.c

  • Committer: Piotr Roszatycki
  • Date: 2011-01-11 14:34:28 UTC
  • mfrom: (1.1.13 upstream)
  • Revision ID: piotr.roszatycki@gmail.com-20110111143428-s7pa7qz38m61o4tw
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (C) 2007-2010, Parrot Foundation.
 
3
 
 
4
=head1 NAME
 
5
 
 
6
src/main.c - the Entry Point to Parrot Programs
 
7
 
 
8
=head1 DESCRIPTION
 
9
 
 
10
Start Parrot
 
11
 
 
12
=head2 Functions
 
13
 
 
14
=over 4
 
15
 
 
16
=cut
 
17
 
 
18
*/
 
19
 
 
20
#include <stdio.h>
 
21
 
 
22
#include "parrot/parrot.h"
 
23
#include "parrot/embed.h"
 
24
#include "parrot/imcc.h"
 
25
#include "parrot/longopt.h"
 
26
#include "parrot/runcore_api.h"
 
27
#include "pmc/pmc_callcontext.h"
 
28
 
 
29
/* For gc_sys_type_enum */
 
30
#include "gc/gc_private.h"
 
31
 
 
32
/* HEADERIZER HFILE: none */
 
33
 
 
34
/* HEADERIZER BEGIN: static */
 
35
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
36
 
 
37
static void help(void);
 
38
static void help_debug(void);
 
39
PARROT_WARN_UNUSED_RESULT
 
40
PARROT_PURE_FUNCTION
 
41
static int is_all_digits(ARGIN(const char *s))
 
42
        __attribute__nonnull__(1);
 
43
 
 
44
PARROT_WARN_UNUSED_RESULT
 
45
PARROT_PURE_FUNCTION
 
46
static int is_all_hex_digits(ARGIN(const char *s))
 
47
        __attribute__nonnull__(1);
 
48
 
 
49
static void Parrot_version(void);
 
50
PARROT_CAN_RETURN_NULL
 
51
static const char * parseflags(PARROT_INTERP,
 
52
    int argc,
 
53
    ARGIN(const char *argv[]),
 
54
    ARGOUT(int *pgm_argc),
 
55
    ARGOUT(const char ***pgm_argv),
 
56
    ARGMOD(Parrot_Run_core_t *core),
 
57
    ARGMOD(Parrot_trace_flags *trace))
 
58
        __attribute__nonnull__(1)
 
59
        __attribute__nonnull__(3)
 
60
        __attribute__nonnull__(4)
 
61
        __attribute__nonnull__(5)
 
62
        __attribute__nonnull__(6)
 
63
        __attribute__nonnull__(7)
 
64
        FUNC_MODIFIES(*pgm_argc)
 
65
        FUNC_MODIFIES(*pgm_argv)
 
66
        FUNC_MODIFIES(*core)
 
67
        FUNC_MODIFIES(*trace);
 
68
 
 
69
static void parseflags_minimal(PARROT_INTERP,
 
70
    int argc,
 
71
    ARGIN(const char *argv[]))
 
72
        __attribute__nonnull__(1)
 
73
        __attribute__nonnull__(3);
 
74
 
 
75
static void usage(ARGMOD(FILE *fp))
 
76
        __attribute__nonnull__(1)
 
77
        FUNC_MODIFIES(*fp);
 
78
 
 
79
#define ASSERT_ARGS_help __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 
80
#define ASSERT_ARGS_help_debug __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 
81
#define ASSERT_ARGS_is_all_digits __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
 
82
       PARROT_ASSERT_ARG(s))
 
83
#define ASSERT_ARGS_is_all_hex_digits __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
 
84
       PARROT_ASSERT_ARG(s))
 
85
#define ASSERT_ARGS_Parrot_version __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 
86
#define ASSERT_ARGS_parseflags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
 
87
       PARROT_ASSERT_ARG(interp) \
 
88
    , PARROT_ASSERT_ARG(argv) \
 
89
    , PARROT_ASSERT_ARG(pgm_argc) \
 
90
    , PARROT_ASSERT_ARG(pgm_argv) \
 
91
    , PARROT_ASSERT_ARG(core) \
 
92
    , PARROT_ASSERT_ARG(trace))
 
93
#define ASSERT_ARGS_parseflags_minimal __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
 
94
       PARROT_ASSERT_ARG(interp) \
 
95
    , PARROT_ASSERT_ARG(argv))
 
96
#define ASSERT_ARGS_usage __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
 
97
       PARROT_ASSERT_ARG(fp))
 
98
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
99
/* HEADERIZER END: static */
 
100
 
 
101
/*
 
102
 
 
103
=item C<int main(int argc, const char *argv[])>
 
104
 
 
105
The entry point from the command line into Parrot.
 
106
 
 
107
=cut
 
108
 
 
109
*/
 
110
 
 
111
int
 
112
main(int argc, const char *argv[])
 
113
{
 
114
    int          stacktop;
 
115
    const char  *sourcefile;
 
116
    const char  *execname;
 
117
    Interp      *interp;
 
118
    int          status;
 
119
    int          pir_argc;
 
120
    const char **pir_argv;
 
121
 
 
122
    Parrot_Run_core_t  core  = PARROT_SLOW_CORE;
 
123
    Parrot_trace_flags trace = PARROT_NO_TRACE;
 
124
 
 
125
    /* internationalization setup */
 
126
    /* setlocale(LC_ALL, ""); */
 
127
    PARROT_BINDTEXTDOMAIN(PACKAGE, LOCALEDIR);
 
128
    PARROT_TEXTDOMAIN(PACKAGE);
 
129
 
 
130
    Parrot_set_config_hash();
 
131
 
 
132
    interp = allocate_interpreter(NULL, PARROT_NO_FLAGS);
 
133
 
 
134
    /* We parse the arguments, but first store away the name of the Parrot
 
135
       executable, since parsing destroys that and we want to make it
 
136
       available. */
 
137
    execname = argv[0];
 
138
 
 
139
    /* Parse minimal subset of flags */
 
140
    parseflags_minimal(interp, argc, argv);
 
141
 
 
142
    /* Now initialize interpreter */
 
143
    initialize_interpreter(interp, (void*)&stacktop);
 
144
 
 
145
    /* Parse flags */
 
146
    sourcefile = parseflags(interp, argc, argv, &pir_argc, &pir_argv, &core, &trace);
 
147
 
 
148
    Parrot_set_trace(interp, trace);
 
149
    Parrot_set_run_core(interp, (Parrot_Run_core_t) core);
 
150
    Parrot_set_executable_name(interp, Parrot_str_new(interp, execname, 0));
 
151
 
 
152
    status = imcc_run(interp, sourcefile, argc, argv);
 
153
 
 
154
    if (status)
 
155
        imcc_run_pbc(interp, interp->output_file, pir_argc, pir_argv);
 
156
 
 
157
    /* Clean-up after ourselves */
 
158
    Parrot_destroy(interp);
 
159
    Parrot_x_exit(interp, 0);
 
160
}
 
161
 
 
162
#define SET_FLAG(flag)   Parrot_set_flag(interp, (flag))
 
163
#define SET_DEBUG(flag)  Parrot_set_debug(interp, (flag))
 
164
#define SET_TRACE(flag)  Parrot_set_trace(interp, (flag))
 
165
 
 
166
/*
 
167
 
 
168
=item C<static int is_all_digits(const char *s)>
 
169
 
 
170
Tests all characters in a string are decimal digits.
 
171
Returns 1 if true, 0 as soon as a non-decimal found
 
172
 
 
173
=cut
 
174
 
 
175
*/
 
176
 
 
177
PARROT_WARN_UNUSED_RESULT
 
178
PARROT_PURE_FUNCTION
 
179
static int
 
180
is_all_digits(ARGIN(const char *s))
 
181
{
 
182
    ASSERT_ARGS(is_all_digits)
 
183
    for (; *s; ++s)
 
184
        if (!isdigit((unsigned char)*s))
 
185
            return 0;
 
186
    return 1;
 
187
}
 
188
 
 
189
/*
 
190
 
 
191
=item C<static int is_all_hex_digits(const char *s)>
 
192
 
 
193
Tests all characters in a string are hexadecimal digits.
 
194
Returns 1 if true, 0 as soon as a non-hex found
 
195
 
 
196
=cut
 
197
 
 
198
*/
 
199
 
 
200
PARROT_WARN_UNUSED_RESULT
 
201
PARROT_PURE_FUNCTION
 
202
static int
 
203
is_all_hex_digits(ARGIN(const char *s))
 
204
{
 
205
    ASSERT_ARGS(is_all_hex_digits)
 
206
    for (; *s; ++s)
 
207
        if (!isxdigit(*s))
 
208
            return 0;
 
209
    return 1;
 
210
}
 
211
 
 
212
/*
 
213
 
 
214
=item C<static void usage(FILE *fp)>
 
215
 
 
216
Outputs usage error message.
 
217
 
 
218
=cut
 
219
 
 
220
*/
 
221
 
 
222
static void
 
223
usage(ARGMOD(FILE *fp))
 
224
{
 
225
    ASSERT_ARGS(usage)
 
226
    fprintf(fp,
 
227
            "parrot -[acEGhprtvVwy.] [-d [FLAGS]] [-D [FLAGS]]"
 
228
            "[-O [level]] [-R runcore] [-o FILE] <file>\n");
 
229
}
 
230
 
 
231
/*
 
232
 
 
233
=item C<static void help_debug(void)>
 
234
 
 
235
Print out list of debugging flag values.
 
236
 
 
237
=cut
 
238
 
 
239
*/
 
240
 
 
241
static void
 
242
help_debug(void)
 
243
{
 
244
    ASSERT_ARGS(help_debug)
 
245
    /* split printf for C89 compliance on string length */
 
246
    printf(
 
247
    "--imcc-debug -d [Flags] ...\n"
 
248
    "    0002    lexer\n"
 
249
    "    0004    parser\n"
 
250
    "    0008    imc\n"
 
251
    "    0010    CFG\n"
 
252
    "    0020    optimization 1\n"
 
253
    "    0040    optimization 2\n"
 
254
    "    0100    AST\n"
 
255
    "    1000    PBC\n"
 
256
    "    2000    PBC constants\n"
 
257
    "    4000    PBC fixups\n"
 
258
    "\n");
 
259
    printf(
 
260
    "--parrot-debug -D [Flags] ...\n"
 
261
    "    0001    memory statistics\n"
 
262
    "    0002    print backtrace on exception\n"
 
263
    "    0004    JIT debugging\n"
 
264
    "    0008    interpreter startup\n"
 
265
    "    0010    thread debugging\n"
 
266
    "    0020    eval/compile\n"
 
267
    "    0040    fill I, N registers with garbage\n"
 
268
    "    0080    show when a context is destroyed\n"
 
269
    "\n"
 
270
    "--trace -t [Flags] ...\n"
 
271
    "    0001    opcodes\n"
 
272
    "    0002    find_method\n"
 
273
    "    0004    function calls\n");
 
274
}
 
275
 
 
276
/*
 
277
 
 
278
=item C<static void help(void)>
 
279
 
 
280
Print out "help" list of options.
 
281
 
 
282
=cut
 
283
 
 
284
*/
 
285
 
 
286
static void
 
287
help(void)
 
288
{
 
289
    ASSERT_ARGS(help)
 
290
    /* split printf for C89 compliance on string length */
 
291
    printf(
 
292
    "parrot [Options] <file>\n"
 
293
    "  Options:\n"
 
294
    "    -h --help\n"
 
295
    "    -V --version\n"
 
296
    "    -I --include add path to include search\n"
 
297
    "    -L --library add path to library search\n"
 
298
    "       --hash-seed F00F  specify hex value to use as hash seed\n"
 
299
    "    -X --dynext add path to dynamic extension search\n"
 
300
    "   <Run core options>\n"
 
301
    "    -R --runcore slow|bounds|fast\n"
 
302
    "    -R --runcore trace|profiling|gcdebug\n"
 
303
    "    -t --trace [flags]\n"
 
304
    "   <VM options>\n"
 
305
    "    -D --parrot-debug[=HEXFLAGS]\n"
 
306
    "       --help-debug\n");
 
307
    printf(
 
308
    "    -w --warnings\n"
 
309
    "    -G --no-gc\n"
 
310
    "       --gc-threshold=percentage    maximum memory wasted by GC\n"
 
311
    "       --gc-debug\n"
 
312
    "       --leak-test|--destroy-at-end\n"
 
313
    "    -g --gc ms|inf set GC type\n"
 
314
    "    -. --wait    Read a keystroke before starting\n"
 
315
    "       --runtime-prefix\n"
 
316
    "   <Compiler options>\n"
 
317
    "    -d --imcc-debug[=HEXFLAGS]\n"
 
318
    "    -v --verbose\n"
 
319
    "    -E --pre-process-only\n"
 
320
    "    -o --output=FILE\n"
 
321
    "       --output-pbc\n"
 
322
    "    -O --optimize[=LEVEL]\n"
 
323
    "    -a --pasm\n"
 
324
    "    -c --pbc\n"
 
325
    "    -r --run-pbc\n"
 
326
    "    -y --yydebug\n"
 
327
    "   <Language options>\n"
 
328
    "see docs/running.pod for more\n");
 
329
}
 
330
 
 
331
 
 
332
/*
 
333
 
 
334
=item C<static void Parrot_version(void)>
 
335
 
 
336
Print out parrot version number.
 
337
 
 
338
=cut
 
339
 
 
340
*/
 
341
 
 
342
static void
 
343
Parrot_version(void)
 
344
{
 
345
    ASSERT_ARGS(Parrot_version)
 
346
    printf("This is Parrot version " PARROT_VERSION);
 
347
    printf(" built for " PARROT_ARCHNAME ".\n");
 
348
    printf("Copyright (C) 2001-2010, Parrot Foundation.\n\
 
349
\n\
 
350
This code is distributed under the terms of the Artistic License 2.0.\
 
351
\n\
 
352
For more details, see the full text of the license in the LICENSE file\
 
353
\n\
 
354
included in the Parrot source tree.\n\n");
 
355
 
 
356
    exit(EXIT_SUCCESS);
 
357
}
 
358
 
 
359
/*
 
360
 
 
361
=item C<static void parseflags_minimal(PARROT_INTERP, int argc, const char
 
362
*argv[])>
 
363
 
 
364
Parse minimal subset of args required for initializing interpreter.
 
365
 
 
366
=cut
 
367
 
 
368
*/
 
369
static void
 
370
parseflags_minimal(PARROT_INTERP, int argc, ARGIN(const char *argv[]))
 
371
{
 
372
    ASSERT_ARGS(parseflags_minimal)
 
373
 
 
374
    int pos = 0;
 
375
 
 
376
    while (pos < argc) {
 
377
        const char *arg = argv[pos];
 
378
 
 
379
        if (STREQ(arg, "--gc")) {
 
380
            ++pos;
 
381
            if (pos == argc) {
 
382
                fprintf(stderr,
 
383
                        "main: No GC specified."
 
384
                        "\n\nhelp: parrot -h\n");
 
385
                exit(EXIT_FAILURE);
 
386
            }
 
387
            arg = argv[pos];
 
388
            if (STREQ(arg, "ms"))
 
389
                interp->gc_sys->sys_type = MS;
 
390
            else if (STREQ(arg, "inf"))
 
391
                interp->gc_sys->sys_type = INF;
 
392
            else if (STREQ(arg, "ms2"))
 
393
                interp->gc_sys->sys_type = MS2;
 
394
            else {
 
395
                fprintf(stderr,
 
396
                        "main: Unrecognized GC '%s' specified."
 
397
                        "\n\nhelp: parrot -h\n", arg);
 
398
                exit(EXIT_FAILURE);
 
399
            }
 
400
            break;
 
401
        }
 
402
 
 
403
        /* arg should start with --gc-threshold *and* contain more chars */
 
404
        else if (strncmp(arg, "--gc-threshold", 14) == 0) {
 
405
 
 
406
            /* the next character could be '=' */
 
407
            if (arg[14] == '=') {
 
408
                arg++;
 
409
            }
 
410
 
 
411
            /* or the end of the string... */
 
412
            else if (arg[14] == '\0'
 
413
 
 
414
            /* and there's another argument */
 
415
                 && pos < argc - 1) {
 
416
                 arg = argv[++pos];
 
417
            }
 
418
 
 
419
            /* ANYTHING ELSE IS WRONG */
 
420
            else {
 
421
                fprintf(stderr, "--gc-threshold needs an argument");
 
422
                exit(EXIT_FAILURE);
 
423
            }
 
424
 
 
425
            if (is_all_digits(arg)) {
 
426
                interp->gc_threshold = strtoul(arg, NULL, 10);
 
427
 
 
428
                if (interp->gc_threshold > 1000) {
 
429
                    fprintf(stderr, "error: maximum GC threshold is 1000\n");
 
430
                    exit(EXIT_FAILURE);
 
431
                }
 
432
            }
 
433
            else {
 
434
                fprintf(stderr, "error: invalid GC threshold specified:"
 
435
                        "'%s'\n", arg);
 
436
                exit(EXIT_FAILURE);
 
437
            }
 
438
            ++pos;
 
439
            arg = argv[pos];
 
440
        }
 
441
        else if (!strncmp(arg, "--hash-seed", 11)) {
 
442
 
 
443
            if ((arg = strrchr(arg, '=')))
 
444
                ++arg;
 
445
            else
 
446
                arg = argv[++pos];
 
447
 
 
448
            if (is_all_hex_digits(arg)) {
 
449
                interp->hash_seed = strtoul(arg, NULL, 16);
 
450
            }
 
451
            else {
 
452
                fprintf(stderr, "error: invalid hash seed specified:"
 
453
                        "'%s'\n", arg);
 
454
                exit(EXIT_FAILURE);
 
455
            }
 
456
            ++pos;
 
457
            arg = argv[pos];
 
458
        }
 
459
        ++pos;
 
460
    }
 
461
}
 
462
 
 
463
/*
 
464
 
 
465
=item C<static const char * parseflags(PARROT_INTERP, int argc, const char
 
466
*argv[], int *pgm_argc, const char ***pgm_argv, Parrot_Run_core_t *core,
 
467
Parrot_trace_flags *trace)>
 
468
 
 
469
Parse Parrot's command line for options and set appropriate flags.
 
470
 
 
471
=cut
 
472
 
 
473
*/
 
474
 
 
475
PARROT_CAN_RETURN_NULL
 
476
static const char *
 
477
parseflags(PARROT_INTERP,
 
478
        int argc, ARGIN(const char *argv[]),
 
479
        ARGOUT(int *pgm_argc), ARGOUT(const char ***pgm_argv),
 
480
        ARGMOD(Parrot_Run_core_t *core), ARGMOD(Parrot_trace_flags *trace))
 
481
{
 
482
    ASSERT_ARGS(parseflags)
 
483
    struct longopt_opt_info opt  = LONGOPT_OPT_INFO_INIT;
 
484
    int                     status;
 
485
 
 
486
    if (argc == 1) {
 
487
        usage(stderr);
 
488
        exit(EXIT_SUCCESS);
 
489
    }
 
490
 
 
491
    while ((status = longopt_get(interp, argc, argv, Parrot_cmd_options(), &opt)) > 0) {
 
492
        switch (opt.opt_id) {
 
493
          case 'R':
 
494
            if (STREQ(opt.opt_arg, "slow") || STREQ(opt.opt_arg, "bounds"))
 
495
                *core = PARROT_SLOW_CORE;
 
496
            else if (STREQ(opt.opt_arg, "fast") || STREQ(opt.opt_arg, "function"))
 
497
                *core = PARROT_FAST_CORE;
 
498
            else if (STREQ(opt.opt_arg, "jit"))
 
499
                *core = PARROT_FAST_CORE;
 
500
            else if (STREQ(opt.opt_arg, "exec"))
 
501
                *core = PARROT_EXEC_CORE;
 
502
            else if (STREQ(opt.opt_arg, "trace"))
 
503
                *core = PARROT_SLOW_CORE;
 
504
            else if (STREQ(opt.opt_arg, "profiling"))
 
505
                *core = PARROT_PROFILING_CORE;
 
506
            else if (STREQ(opt.opt_arg, "gcdebug"))
 
507
                *core = PARROT_GC_DEBUG_CORE;
 
508
            else {
 
509
                fprintf(stderr,
 
510
                        "main: Unrecognized runcore '%s' specified."
 
511
                        "\n\nhelp: parrot -h\n", opt.opt_arg);
 
512
                exit(EXIT_FAILURE);
 
513
            }
 
514
            break;
 
515
          case 'g':
 
516
            /* Handled in parseflags_minimal */
 
517
            break;
 
518
          case OPT_GC_THRESHOLD:
 
519
            /* handled in parseflags_minimal */
 
520
            break;
 
521
          case 't':
 
522
            if (opt.opt_arg && is_all_hex_digits(opt.opt_arg)) {
 
523
                const unsigned long _temp = strtoul(opt.opt_arg, NULL, 16);
 
524
                const Parrot_trace_flags _temp_flag = (Parrot_trace_flags)_temp;
 
525
                *trace = _temp_flag;
 
526
            }
 
527
            else
 
528
                *trace = PARROT_TRACE_OPS_FLAG;
 
529
            break;
 
530
          case 'D':
 
531
            if (opt.opt_arg && is_all_hex_digits(opt.opt_arg)) {
 
532
                SET_DEBUG(strtoul(opt.opt_arg, NULL, 16));
 
533
            }
 
534
            else
 
535
                SET_DEBUG(PARROT_MEM_STAT_DEBUG_FLAG);
 
536
            break;
 
537
 
 
538
          case '.':  /* Give Windows Parrot hackers an opportunity to
 
539
                      * attach a debuggger. */
 
540
            fgetc(stdin);
 
541
            break;
 
542
          case 'h':
 
543
            help();
 
544
            exit(EXIT_FAILURE);
 
545
            break;
 
546
          case OPT_HASH_SEED:
 
547
            /* handled in parseflags_minimal */
 
548
            break;
 
549
          case OPT_HELP_DEBUG:
 
550
            help_debug();
 
551
            exit(EXIT_FAILURE);
 
552
            break;
 
553
          case OPT_RUNTIME_PREFIX:
 
554
            Parrot_io_printf(interp, "%Ss\n",
 
555
                    Parrot_get_runtime_path(interp));
 
556
            exit(EXIT_SUCCESS);
 
557
          case 'V':
 
558
            Parrot_version();
 
559
            break;
 
560
 
 
561
          case OPT_GC_DEBUG:
 
562
#if DISABLE_GC_DEBUG
 
563
            Parrot_warn(interp, PARROT_WARNINGS_ALL_FLAG,
 
564
                "PARROT_GC_DEBUG is set but the binary was compiled "
 
565
                "with DISABLE_GC_DEBUG.");
 
566
#endif
 
567
            SET_FLAG(PARROT_GC_DEBUG_FLAG);
 
568
            break;
 
569
          case OPT_DESTROY_FLAG:
 
570
            SET_FLAG(PARROT_DESTROY_FLAG);
 
571
            break;
 
572
          case 'I':
 
573
            Parrot_lib_add_path_from_cstring(interp, opt.opt_arg,
 
574
                    PARROT_LIB_PATH_INCLUDE);
 
575
            break;
 
576
          case 'L':
 
577
            Parrot_lib_add_path_from_cstring(interp, opt.opt_arg,
 
578
                    PARROT_LIB_PATH_LIBRARY);
 
579
            break;
 
580
          case 'X':
 
581
            Parrot_lib_add_path_from_cstring(interp, opt.opt_arg,
 
582
                    PARROT_LIB_PATH_DYNEXT);
 
583
            break;
 
584
          case 'w':
 
585
            /* FIXME It's not best way to set warnings... */
 
586
            Parrot_setwarnings(interp, PARROT_WARNINGS_ALL_FLAG);
 
587
            break;
 
588
          case 'o':
 
589
            interp->output_file = opt.opt_arg;
 
590
            break;
 
591
          case OPT_PBC_OUTPUT:
 
592
            if (!interp->output_file)
 
593
                interp->output_file = "-";
 
594
          default:
 
595
            /* languages handle their arguments later (after being initialized) */
 
596
            break;
 
597
        }
 
598
    }
 
599
 
 
600
    if (status == -1) {
 
601
        fprintf(stderr, "%s\n", opt.opt_error);
 
602
        usage(stderr);
 
603
        exit(EXIT_FAILURE);
 
604
    }
 
605
 
 
606
    /* reached the end of the option list and consumed all of argv */
 
607
    if (argc == opt.opt_index) {
 
608
        if (interp->output_file) {
 
609
            fprintf(stderr, "Missing program name or argument for -o\n");
 
610
        }
 
611
        else {
 
612
            /* We are not looking at an option, so it must be a program name */
 
613
            fprintf(stderr, "Missing program name\n");
 
614
        }
 
615
        usage(stderr);
 
616
        exit(EXIT_FAILURE);
 
617
    }
 
618
 
 
619
    *pgm_argc = argc - opt.opt_index;
 
620
    *pgm_argv = argv + opt.opt_index;
 
621
 
 
622
    return (*pgm_argv)[0];
 
623
}
 
624
/*
 
625
 
 
626
=back
 
627
 
 
628
=head1 SEE ALSO
 
629
 
 
630
F<compilers/imcc/main.c>, unfortunately.
 
631
 
 
632
=cut
 
633
 
 
634
*/
 
635
 
 
636
/*
 
637
 * Local variables:
 
638
 *   c-file-style: "parrot"
 
639
 * End:
 
640
 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
 
641
 */