diff options
Diffstat (limited to 'interpret.h')
-rw-r--r-- | interpret.h | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/interpret.h b/interpret.h index 29feb821..28804330 100644 --- a/interpret.h +++ b/interpret.h @@ -1038,10 +1038,44 @@ match_re: f = lookup(t1->stptr); } - if (f == NULL || f->type != Node_func) { - if (f->type == Node_ext_func || f->type == Node_old_ext_func) - fatal(_("cannot (yet) call extension functions indirectly")); - else + if (f == NULL) { + fatal(_("`%s' is not a function, so it cannot be called indirectly"), + t1->stptr); + } else if (f->type == Node_builtin_func) { + int arg_count = (pc + 1)->expr_count; + builtin_func_t the_func = lookup_builtin(t1->stptr); + + assert(the_func != NULL); + + /* call it */ + r = the_func(arg_count); + PUSH(r); + break; + } else if (f->type != Node_func) { + if ( f->type == Node_ext_func + || f->type == Node_old_ext_func) { + /* code copied from below, keep in sync */ + INSTRUCTION *bc; + char *fname = pc->func_name; + int arg_count = (pc + 1)->expr_count; + static INSTRUCTION npc[2]; + + npc[0] = *pc; + + bc = f->code_ptr; + assert(bc->opcode == Op_symbol); + if (f->type == Node_ext_func) + npc[0].opcode = Op_ext_builtin; /* self modifying code */ + else + npc[0].opcode = Op_old_ext_builtin; /* self modifying code */ + npc[0].extfunc = bc->extfunc; + npc[0].expr_count = arg_count; /* actual argument count */ + npc[1] = pc[1]; + npc[1].func_name = fname; /* name of the builtin */ + npc[1].expr_count = bc->expr_count; /* defined max # of arguments */ + ni = npc; + JUMPTO(ni); + } else fatal(_("function called indirectly through `%s' does not exist"), pc->func_name); } @@ -1065,6 +1099,7 @@ match_re: } if (f->type == Node_ext_func || f->type == Node_old_ext_func) { + /* keep in sync with indirect call code */ INSTRUCTION *bc; char *fname = pc->func_name; int arg_count = (pc + 1)->expr_count; @@ -1098,10 +1133,6 @@ match_re: JUMPTO(ni); case Op_K_getline_redir: - if ((currule == BEGINFILE || currule == ENDFILE) - && pc->into_var == false - && pc->redir_type == redirect_input) - fatal(_("`getline' invalid inside `%s' rule"), ruletab[currule]); r = do_getline_redir(pc->into_var, pc->redir_type); PUSH(r); break; @@ -1195,10 +1226,13 @@ match_re: JUMPTO(ni); } - if (inrec(curfile, & errcode) != 0) { - if (errcode > 0 && (do_traditional || ! pc->has_endfile)) - fatal(_("error reading input file `%s': %s"), + if (! inrec(curfile, & errcode)) { + if (errcode > 0) { + update_ERRNO_int(errcode); + if (do_traditional || ! pc->has_endfile) + fatal(_("error reading input file `%s': %s"), curfile->public.name, strerror(errcode)); + } JUMPTO(ni); } /* else |