~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to interpret.h

  • Committer: Arnold D. Robbins
  • Date: 2012-11-25 19:54:48 UTC
  • mfrom: (319.1.122)
  • Revision ID: git-v1:9a9ff61bbd952c1263b55f82a269da5b09289a6b
Merge branch 'master' into array-iface

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
 
43
43
 
44
44
/* array subscript */
45
 
#define mk_sub(n)       (n == 1 ? POP_SCALAR() : concat_exp(n, TRUE))
 
45
#define mk_sub(n)       (n == 1 ? POP_SCALAR() : concat_exp(n, true))
46
46
 
47
47
#ifdef EXEC_HOOK
48
 
#define JUMPTO(x)       do { if (post_execute) post_execute(pc); pc = (x); goto top; } while (FALSE)
 
48
#define JUMPTO(x)       do { if (post_execute) post_execute(pc); pc = (x); goto top; } while (false)
49
49
#else
50
 
#define JUMPTO(x)       do { pc = (x); goto top; } while (FALSE)
 
50
#define JUMPTO(x)       do { pc = (x); goto top; } while (false)
51
51
#endif
52
52
 
53
53
        pc = code;
82
82
 
83
83
                case Op_atexit:
84
84
                {
85
 
                        int stdio_problem = FALSE;
 
85
                        bool stdio_problem = false;
86
86
 
87
87
                        /* avoid false source indications */
88
88
                        source = NULL;
89
89
                        sourceline = 0;
90
 
                        (void) nextfile(& curfile, TRUE);       /* close input data file */ 
 
90
                        (void) nextfile(& curfile, true);       /* close input data file */ 
91
91
                        /*
92
92
                         * This used to be:
93
93
                         *
134
134
                case Op_push_arg:
135
135
                {
136
136
                        NODE *save_symbol;
137
 
                        int isparam = FALSE;
 
137
                        bool isparam = false;
138
138
 
139
139
                        save_symbol = m = pc->memory;
140
140
                        if (m->type == Node_param_list) {
141
 
                                isparam = TRUE;
 
141
                                isparam = true;
142
142
                                save_symbol = m = GET_PARAM(m->param_cnt);
143
143
                                if (m->type == Node_array_ref)
144
144
                                        m = m->orig_array;
215
215
                                        lintwarn(_("subscript of array `%s' is null string"), array_vname(t1));
216
216
                        }
217
217
 
218
 
                        r = *assoc_lookup(t1, t2);
 
218
                        /* for FUNCTAB, get the name as the element value */
 
219
                        if (t1 == func_table) {
 
220
                                static bool warned = false;
 
221
                                
 
222
                                if (do_lint && ! warned) {
 
223
                                        warned = true;
 
224
                                        lintwarn(_("FUNCTAB is a gawk extension"));
 
225
                                }
 
226
                                r = t2;
 
227
                        } else {
 
228
                                r = *assoc_lookup(t1, t2);
 
229
                        }
219
230
                        DEREF(t2);
 
231
 
 
232
                        /* for SYMTAB, step through to the actual variable */
 
233
                        if (t1 == symbol_table) {
 
234
                                static bool warned = false;
 
235
                                
 
236
                                if (do_lint && ! warned) {
 
237
                                        warned = true;
 
238
                                        lintwarn(_("SYMTAB is a gawk extension"));
 
239
                                }
 
240
                                if (r->type == Node_var)
 
241
                                        r = r->var_value;
 
242
                        }
 
243
 
220
244
                        if (r->type == Node_val)
221
245
                                UPREF(r);
222
246
                        PUSH(r);
267
291
                                                array_vname(t1), (int) t2->stlen, t2->stptr);
268
292
                        }
269
293
 
 
294
                        /*
 
295
                         * Changing something in FUNCTAB is not allowed.
 
296
                         *
 
297
                         * SYMTAB is a little more messy.  Three kinds of values may
 
298
                         * be stored in SYMTAB:
 
299
                         *      1. Variables that don"t yet have a value (Node_var_new)
 
300
                         *      2. Variables that have a value (Node_var)
 
301
                         *      3. Values that awk code stuck into SYMTAB not related to variables (Node_value)
 
302
                         * For 1, since we are giving it a value, we have to change the type to Node_var.
 
303
                         * For 1 and 2, we have to step through the Node_var to get to the value.
 
304
                         * For 3, we just us the value we got from assoc_lookup(), above.
 
305
                         */
 
306
                        if (t1 == func_table)
 
307
                                fatal(_("cannot assign to elements of FUNCTAB"));
 
308
                        else if (   t1 == symbol_table
 
309
                                 && (   (*lhs)->type == Node_var
 
310
                                     || (*lhs)->type == Node_var_new)) {
 
311
                                (*lhs)->type = Node_var;        /* in case was Node_var_new */
 
312
                                lhs = & ((*lhs)->var_value);    /* extra level of indirection */
 
313
                        }
 
314
 
270
315
                        assert(set_idx == NULL);
271
316
 
272
317
                        if (t1->astore) {
281
326
 
282
327
                case Op_field_spec:
283
328
                        t1 = TOP_SCALAR();
284
 
                        lhs = r_get_field(t1, (Func_ptr *) 0, TRUE);
 
329
                        lhs = r_get_field(t1, (Func_ptr *) 0, true);
285
330
                        decr_sp();
286
331
                        DEREF(t1);
287
332
                        r = dupnode(*lhs);     /* can't use UPREF here */
316
361
                case Op_K_break:
317
362
                case Op_K_continue:
318
363
                case Op_jmp:
 
364
                        assert(pc->target_jmp != NULL);
319
365
                        JUMPTO(pc->target_jmp);
320
366
 
321
367
                case Op_jmp_false:
542
588
                         * array[sub] assignment optimization,
543
589
                         * see awkgram.y (optimize_assignment)
544
590
                         */
545
 
                        t1 = force_array(pc->memory, TRUE);     /* array */
 
591
                        t1 = force_array(pc->memory, true);     /* array */
546
592
                        t2 = mk_sub(pc->expr_count);    /* subscript */
547
593
                        lhs = assoc_lookup(t1, t2);
548
594
                        if ((*lhs)->type == Node_var_array) {
550
596
                                fatal(_("attempt to use array `%s[\"%.*s\"]' in a scalar context"),
551
597
                                                array_vname(t1), (int) t2->stlen, t2->stptr);
552
598
                        }
 
599
                        DEREF(t2);
 
600
 
 
601
                        /*
 
602
                         * Changing something in FUNCTAB is not allowed.
 
603
                         *
 
604
                         * SYMTAB is a little more messy.  Three kinds of values may
 
605
                         * be stored in SYMTAB:
 
606
                         *      1. Variables that don"t yet have a value (Node_var_new)
 
607
                         *      2. Variables that have a value (Node_var)
 
608
                         *      3. Values that awk code stuck into SYMTAB not related to variables (Node_value)
 
609
                         * For 1, since we are giving it a value, we have to change the type to Node_var.
 
610
                         * For 1 and 2, we have to step through the Node_var to get to the value.
 
611
                         * For 3, we just us the value we got from assoc_lookup(), above.
 
612
                         */
 
613
                        if (t1 == func_table)
 
614
                                fatal(_("cannot assign to elements of FUNCTAB"));
 
615
                        else if (   t1 == symbol_table
 
616
                                 && (   (*lhs)->type == Node_var
 
617
                                     || (*lhs)->type == Node_var_new)) {
 
618
                                (*lhs)->type = Node_var;        /* in case was Node_var_new */
 
619
                                lhs = & ((*lhs)->var_value);    /* extra level of indirection */
 
620
                        }
 
621
 
553
622
                        unref(*lhs);
554
623
                        *lhs = POP_SCALAR();
555
624
 
566
635
                         * see awkgram.y (optimize_assignment)
567
636
                         */
568
637
        
569
 
                        lhs = get_lhs(pc->memory, FALSE);
 
638
                        lhs = get_lhs(pc->memory, false);
570
639
                        unref(*lhs);
571
640
                        r = pc->initval;        /* constant initializer */
572
641
                        if (r == NULL)
585
654
 
586
655
                        Func_ptr assign;
587
656
                        t1 = TOP_SCALAR();
588
 
                        lhs = r_get_field(t1, & assign, FALSE);
 
657
                        lhs = r_get_field(t1, & assign, false);
589
658
                        decr_sp();
590
659
                        DEREF(t1);
591
660
                        unref(*lhs);
597
666
 
598
667
                case Op_assign_concat:
599
668
                        /* x = x ... string concatenation optimization */
600
 
                        lhs = get_lhs(pc->memory, FALSE);
 
669
                        lhs = get_lhs(pc->memory, false);
601
670
                        t1 = force_string(*lhs);
602
671
                        t2 = POP_STRING();
603
672
 
642
711
                        /* conditionally execute post-assignment routine for an array element */ 
643
712
 
644
713
                        if (set_idx != NULL) {
645
 
                                di = TRUE;
 
714
                                di = true;
646
715
                                if (pc->assign_ctxt == Op_sub_builtin
647
716
                                        && (r = TOP())
648
717
                                        && get_number_si(r) == 0        /* no substitution performed */
649
718
                                )
650
 
                                        di = FALSE;
 
719
                                        di = false;
651
720
                                else if ((pc->assign_ctxt == Op_K_getline
652
721
                                                || pc->assign_ctxt == Op_K_getline_redir)
653
722
                                        && (r = TOP())
654
723
                                        && get_number_si(r) <= 0        /* EOF or error */
655
724
                                )
656
 
                                        di = FALSE;
 
725
                                        di = false;
657
726
 
658
727
                                if (di)
659
728
                                        (*set_array->astore)(set_array, set_idx);
765
834
                        /* get the array */
766
835
                        array = POP_ARRAY();
767
836
 
 
837
                        /* sanity: check if empty */
 
838
                        num_elems = assoc_length(array);
 
839
                        if (num_elems == 0)
 
840
                                goto arrayfor;
 
841
 
768
842
                        if (sorted_in == NULL)          /* do this once */
769
843
                                sorted_in = make_string("sorted_in", 9);
770
844
 
784
858
 
785
859
                        list = assoc_list(array, how_to_sort, SORTED_IN);
786
860
 
787
 
                        num_elems = assoc_length(array);
788
 
 
 
861
arrayfor:
789
862
                        getnode(r);
790
863
                        r->type = Node_arrayfor;
791
864
                        r->for_list = list;
811
884
                        }
812
885
 
813
886
                        t1 = r->for_list[r->cur_idx];
814
 
                        lhs = get_lhs(pc->array_var, FALSE);
 
887
                        lhs = get_lhs(pc->array_var, false);
815
888
                        unref(*lhs);
816
889
                        *lhs = dupnode(t1);
817
890
                        break;
830
903
                case Op_ext_builtin:
831
904
                {
832
905
                        int arg_count = pc->expr_count;
 
906
                        awk_value_t result;
833
907
 
834
908
                        PUSH_CODE(pc);
835
 
                        r = pc->builtin(arg_count);
 
909
                        r = awk_value_to_node(pc->extfunc(arg_count, & result));
836
910
                        (void) POP_CODE();
837
911
                        while (arg_count-- > 0) {
838
912
                                t1 = POP();
920
994
 
921
995
                        arg_count = (pc + 1)->expr_count;
922
996
                        t1 = PEEK(arg_count);   /* indirect var */
923
 
                        assert(t1->type == Node_val);   /* @a[1](p) not allowed in grammar */
 
997
 
 
998
                        if (t1->type != Node_val)       /* @a[1](p) not allowed in grammar */
 
999
                                fatal(_("indirect function call requires a simple scalar value"));
 
1000
 
924
1001
                        t1 = force_string(t1);
925
1002
                        if (t1->stlen > 0) {
926
1003
                                /* retrieve function definition node */
934
1011
                                f = lookup(t1->stptr);
935
1012
                        }
936
1013
 
937
 
                        if (f == NULL || f->type != Node_func)
938
 
                                fatal(_("function called indirectly through `%s' does not exist"),
939
 
                                                pc->func_name); 
 
1014
                        if (f == NULL || f->type != Node_func) {
 
1015
                                if (f->type == Node_ext_func)
 
1016
                                        fatal(_("cannot (yet) call extension functions indirectly"));
 
1017
                                else
 
1018
                                        fatal(_("function called indirectly through `%s' does not exist"),
 
1019
                                                        pc->func_name); 
 
1020
                        }
940
1021
                        pc->func_body = f;     /* save for next call */
941
1022
 
942
1023
                        ni = setup_frame(pc);
964
1045
                                bc = f->code_ptr;
965
1046
                                assert(bc->opcode == Op_symbol);
966
1047
                                pc->opcode = Op_ext_builtin;    /* self modifying code */
967
 
                                pc->builtin = bc->builtin;
 
1048
                                pc->extfunc = bc->extfunc;
968
1049
                                pc->expr_count = arg_count;             /* actual argument count */
969
1050
                                (pc + 1)->func_name = fname;    /* name of the builtin */
970
1051
                                (pc + 1)->expr_count = bc->expr_count;  /* defined max # of arguments */
988
1069
 
989
1070
                case Op_K_getline_redir:
990
1071
                        if ((currule == BEGINFILE || currule == ENDFILE)
991
 
                                        && pc->into_var == FALSE
 
1072
                                        && pc->into_var == false
992
1073
                                        && pc->redir_type == redirect_input)
993
1074
                                fatal(_("`getline' invalid inside `%s' rule"), ruletab[currule]);
994
1075
                        r = do_getline_redir(pc->into_var, pc->redir_type);
1002
1083
 
1003
1084
                        do {
1004
1085
                                int ret;
1005
 
                                ret = nextfile(& curfile, FALSE);
 
1086
                                ret = nextfile(& curfile, false);
1006
1087
                                if (ret <= 0)
1007
1088
                                        r = do_getline(pc->into_var, curfile);
1008
1089
                                else {
1048
1129
                {
1049
1130
                        int ret;
1050
1131
 
1051
 
                        ret = nextfile(& curfile, FALSE);
 
1132
                        ret = nextfile(& curfile, false);
1052
1133
 
1053
1134
                        if (ret < 0)    /* end of input */
1054
1135
                                JUMPTO(pc->target_jmp); /* end block or Op_atexit */
1087
1168
                        if (inrec(curfile, & errcode) != 0) {
1088
1169
                                if (errcode > 0 && (do_traditional || ! pc->has_endfile))
1089
1170
                                        fatal(_("error reading input file `%s': %s"),
1090
 
                                                curfile->name, strerror(errcode));
 
1171
                                                curfile->public.name, strerror(errcode));
1091
1172
 
1092
1173
                                JUMPTO(ni);
1093
1174
                        } /* else
1103
1184
                                fatal(_("`nextfile' cannot be called from a `%s' rule"),
1104
1185
                                        ruletab[currule]);
1105
1186
 
1106
 
                        ret = nextfile(& curfile, TRUE);        /* skip current file */
 
1187
                        ret = nextfile(& curfile, true);        /* skip current file */
1107
1188
 
1108
1189
                        if (currule == BEGINFILE) {
1109
1190
                                long stack_size;
1149
1230
                        if (! currule)
1150
1231
                                fatal(_("`exit' cannot be called in the current context"));
1151
1232
 
1152
 
                        exiting = TRUE;
 
1233
                        exiting = true;
1153
1234
                        t1 = POP_NUMBER();
1154
1235
                        exit_val = (int) get_number_si(t1);
1155
1236
                        DEREF(t1);
1216
1297
                        ip = pc->line_range;            /* Op_line_range */
1217
1298
 
1218
1299
                        if (! ip->triggered && di) {
1219
 
                                /* not already triggered and left expression is TRUE */
 
1300
                                /* not already triggered and left expression is true */
1220
1301
                                decr_sp();
1221
 
                                ip->triggered = TRUE;
 
1302
                                ip->triggered = true;
1222
1303
                                JUMPTO(ip->target_jmp); /* evaluate right expression */ 
1223
1304
                        }
1224
1305