source: trunk/package/busybox/patches/510-awk_include.patch @ 22659

Last change on this file since 22659 was 22659, checked in by acoul, 6 years ago

package/busybox: update to busybox-1.7.1, include upstream patches

File size: 4.7 KB
  • editors/awk.c

    a b typedef struct chain_s { 
    7070} chain; 
    7171 
    7272/* Function */ 
     73typedef var *(*awk_cfunc)(var *res, var *args, int nargs); 
    7374typedef struct func_s { 
    7475        unsigned nargs; 
     76        enum { AWKFUNC, CFUNC } type; 
     77        union { 
     78                awk_cfunc cfunc; 
    7579        struct chain_s body; 
     80        } x; 
    7681} func; 
    7782 
    7883/* I/O stream */ 
    static void parse_program(char *p) 
    14531458                        next_token(TC_FUNCTION); 
    14541459                        g_pos++; 
    14551460                        f = newfunc(t_string); 
    1456                         f->body.first = NULL; 
     1461                        f->type = AWKFUNC; 
     1462                        f->x.body.first = NULL; 
    14571463                        f->nargs = 0; 
    14581464                        while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { 
    14591465                                v = findvar(ahash, t_string); 
    static void parse_program(char *p) 
    14621468                                if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) 
    14631469                                        break; 
    14641470                        } 
    1465                         seq = &f->body; 
     1471                        seq = &f->x.body; 
    14661472                        chain_group(); 
    14671473                        clear_array(ahash); 
    14681474 
    static var *evaluate(node *op, var *res) 
    25472553                        var *vbeg, *v; 
    25482554                        const char *sv_progname; 
    25492555 
    2550                         if (!op->r.f->body.first) 
     2556                        if ((op->r.f->type == AWKFUNC) && 
     2557                                !op->r.f->x.body.first) 
    25512558                                syntax_error(EMSG_UNDEF_FUNC); 
    25522559 
    25532560                        vbeg = v = nvalloc(op->r.f->nargs + 1); 
    static var *evaluate(node *op, var *res) 
    25642571                        fnargs = vbeg; 
    25652572                        sv_progname = g_progname; 
    25662573 
    2567                         res = evaluate(op->r.f->body.first, res); 
     2574                        if (op->r.f->type == AWKFUNC) 
     2575                                res = evaluate(op->r.f->x.body.first, res); 
     2576                        else if (op->r.f->type == CFUNC) 
     2577                                res = op->r.f->x.cfunc(res, fnargs, op->r.f->nargs); 
    25682578 
    25692579                        g_progname = sv_progname; 
    25702580                        nvfree(fnargs); 
    static rstream *next_input_file(void) 
    29422952#undef files_happen 
    29432953} 
    29442954 
     2955/* read the contents of an entire file */ 
     2956static char *get_file(const char *fname) 
     2957{ 
     2958        FILE *F; 
     2959        char *s = NULL; 
     2960        int i, j, flen; 
     2961 
     2962        F = fopen(fname, "r"); 
     2963        if (!F) { 
     2964                return NULL; 
     2965        } 
     2966 
     2967        if (fseek(F, 0, SEEK_END) == 0) { 
     2968                flen = ftell(F); 
     2969                s = (char *)xmalloc(flen+4); 
     2970                fseek(F, 0, SEEK_SET); 
     2971                i = 1 + fread(s+1, 1, flen, F); 
     2972        } else { 
     2973                for (i=j=1; j>0; i+=j) { 
     2974                        s = (char *)xrealloc(s, i+4096); 
     2975                        j = fread(s+i, 1, 4094, F); 
     2976                } 
     2977        } 
     2978 
     2979        s[i] = '\0'; 
     2980        fclose(F); 
     2981        return s; 
     2982} 
     2983 
     2984 
     2985/* parse_include(): 
     2986 * 
     2987 * taken from parse_program from awk.c 
     2988 * END{} is not parsed here, and BEGIN{} is executed immediately 
     2989 */ 
     2990static void parse_include(char *p) 
     2991{ 
     2992        uint32_t tclass; 
     2993        chain *initseq = NULL; 
     2994        chain tmp; 
     2995        func *f; 
     2996        var *v, *tv; 
     2997 
     2998        tv = nvalloc(1); 
     2999        memset(&tmp, 0, sizeof(tmp)); 
     3000        g_pos = p; 
     3001        t_lineno = 1; 
     3002        while ((tclass = next_token(TC_EOF | TC_OPSEQ | 
     3003                                TC_OPTERM | TC_BEGIN | TC_FUNCDECL)) != TC_EOF) { 
     3004                if (tclass & TC_OPTERM) 
     3005                        continue; 
     3006 
     3007                seq = &tmp; 
     3008                if (tclass & TC_BEGIN) { 
     3009                        initseq = xzalloc(sizeof(chain)); 
     3010                        seq = initseq; 
     3011                        chain_group(); 
     3012                } else if (tclass & TC_FUNCDECL) { 
     3013                        next_token(TC_FUNCTION); 
     3014                        g_pos++; 
     3015                        f = newfunc(t_string); 
     3016                        f->type = AWKFUNC; 
     3017                        f->x.body.first = NULL; 
     3018                        f->nargs = 0; 
     3019                        while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { 
     3020                                v = findvar(ahash, t_string); 
     3021                                v->x.aidx = (f->nargs)++; 
     3022 
     3023                                if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) 
     3024                                        break; 
     3025                        } 
     3026                        seq = &(f->x.body); 
     3027                        chain_group(); 
     3028                        clear_array(ahash); 
     3029                } 
     3030        } 
     3031        if (initseq && initseq->first) 
     3032                tv = evaluate(initseq->first, tv); 
     3033        nvfree(tv); 
     3034} 
     3035 
     3036 
     3037/* include an awk file and run its BEGIN{} section */ 
     3038static xhash *includes = NULL; 
     3039static void include_file(const char *filename) 
     3040{ 
     3041        char *s; 
     3042        var *v; 
     3043        int oldlnr = g_lineno; 
     3044        const char *oldprg = g_progname; 
     3045 
     3046        if (!includes) 
     3047                includes = hash_init(); 
     3048 
     3049        /* find out if the file has been included already */ 
     3050        v = findvar(includes, filename); 
     3051        if (istrue(v)) 
     3052                return; 
     3053        setvar_s(v, "1"); 
     3054 
     3055        /* read include file */ 
     3056        s = get_file(filename); 
     3057        if (!s) { 
     3058                fprintf(stderr, "Could not open file.\n"); 
     3059                return; 
     3060        } 
     3061        g_lineno = 1; 
     3062        g_progname = xstrdup(filename); 
     3063        parse_include(s+1); 
     3064        free(s); 
     3065        g_lineno = oldlnr; 
     3066        g_progname = oldprg; 
     3067} 
     3068 
     3069static var *include(var *res, var *args, int nargs) 
     3070{ 
     3071        const char *s; 
     3072 
     3073        nargs = nargs; /* shut up, gcc */ 
     3074        s = getvar_s(args); 
     3075        if (s && (strlen(s) > 0)) 
     3076                include_file(s); 
     3077 
     3078        return res; 
     3079} 
     3080 
     3081/* registers a global c function for the awk interpreter */ 
     3082static void register_cfunc(const char *name, awk_cfunc cfunc, int nargs) 
     3083{ 
     3084        func *f; 
     3085 
     3086        f = newfunc(name); 
     3087        f->type = CFUNC; 
     3088        f->x.cfunc = cfunc; 
     3089        f->nargs = nargs; 
     3090} 
     3091 
    29453092int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 
    29463093int awk_main(int argc, char **argv) 
    29473094{ 
    int awk_main(int argc, char **argv) 
    30073154                        *s1 = '='; 
    30083155                } 
    30093156        } 
     3157 
     3158        register_cfunc("include", include, 1); 
     3159 
    30103160        opt_complementary = "v::f::"; /* -v and -f can occur multiple times */ 
    30113161        opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, &opt_W); 
    30123162        argv += optind; 
Note: See TracBrowser for help on using the repository browser.