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

Last change on this file since 20661 was 20661, checked in by nico, 6 years ago

[package] busybox: update to v1.16.1 (based on v1.16.0 update patch from Peter Wagner)

File size: 4.7 KB
  • editors/awk.c

    a b typedef struct chain_s { 
    5353} chain; 
    5454 
    5555/* Function */ 
     56typedef var *(*awk_cfunc)(var *res, var *args, int nargs); 
    5657typedef struct func_s { 
    5758        unsigned nargs; 
     59        enum { AWKFUNC, CFUNC } type; 
     60        union { 
     61                awk_cfunc cfunc; 
    5862        struct chain_s body; 
     63        } x; 
    5964} func; 
    6065 
    6166/* I/O stream */ 
    static void parse_program(char *p) 
    14241429                        next_token(TC_FUNCTION); 
    14251430                        g_pos++; 
    14261431                        f = newfunc(t_string); 
    1427                         f->body.first = NULL; 
     1432                        f->type = AWKFUNC; 
     1433                        f->x.body.first = NULL; 
    14281434                        f->nargs = 0; 
    14291435                        while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { 
    14301436                                v = findvar(ahash, t_string); 
    static void parse_program(char *p) 
    14331439                                if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) 
    14341440                                        break; 
    14351441                        } 
    1436                         seq = &(f->body); 
     1442                        seq = &(f->x.body); 
    14371443                        chain_group(); 
    14381444                        clear_array(ahash); 
    14391445 
    static var *evaluate(node *op, var *res) 
    24462452                        break; 
    24472453 
    24482454                case XC( OC_FUNC ): 
    2449                         if (!op->r.f->body.first) 
     2455                        if ((op->r.f->type == AWKFUNC) && 
     2456                                !op->r.f->x.body.first) 
    24502457                                syntax_error(EMSG_UNDEF_FUNC); 
    24512458 
    24522459                        X.v = R.v = nvalloc(op->r.f->nargs + 1); 
    static var *evaluate(node *op, var *res) 
    24632470                        fnargs = X.v; 
    24642471 
    24652472                        L.s = g_progname; 
    2466                         res = evaluate(op->r.f->body.first, res); 
     2473                        if (op->r.f->type == AWKFUNC) 
     2474                                res = evaluate(op->r.f->x.body.first, res); 
     2475                        else if (op->r.f->type == CFUNC) 
     2476                                res = op->r.f->x.cfunc(res, fnargs, op->r.f->nargs); 
    24672477                        g_progname = L.s; 
    24682478 
    24692479                        nvfree(fnargs); 
    static rstream *next_input_file(void) 
    28292839#undef files_happen 
    28302840} 
    28312841 
     2842/* read the contents of an entire file */ 
     2843static char *get_file(const char *fname) 
     2844{ 
     2845        FILE *F; 
     2846        char *s = NULL; 
     2847        int i, j, flen; 
     2848 
     2849        F = fopen(fname, "r"); 
     2850        if (!F) { 
     2851                return NULL; 
     2852        } 
     2853 
     2854        if (fseek(F, 0, SEEK_END) == 0) { 
     2855                flen = ftell(F); 
     2856                s = (char *)xmalloc(flen+4); 
     2857                fseek(F, 0, SEEK_SET); 
     2858                i = 1 + fread(s+1, 1, flen, F); 
     2859        } else { 
     2860                for (i=j=1; j>0; i+=j) { 
     2861                        s = (char *)xrealloc(s, i+4096); 
     2862                        j = fread(s+i, 1, 4094, F); 
     2863                } 
     2864        } 
     2865 
     2866        s[i] = '\0'; 
     2867        fclose(F); 
     2868        return s; 
     2869} 
     2870 
     2871 
     2872/* parse_include(): 
     2873 * 
     2874 * taken from parse_program from awk.c 
     2875 * END{} is not parsed here, and BEGIN{} is executed immediately 
     2876 */ 
     2877static void parse_include(char *p) 
     2878{ 
     2879        uint32_t tclass; 
     2880        chain *initseq = NULL; 
     2881        chain tmp; 
     2882        func *f; 
     2883        var *v, *tv; 
     2884 
     2885        tv = nvalloc(1); 
     2886        memset(&tmp, 0, sizeof(tmp)); 
     2887        g_pos = p; 
     2888        t_lineno = 1; 
     2889        while ((tclass = next_token(TC_EOF | TC_OPSEQ | 
     2890                                TC_OPTERM | TC_BEGIN | TC_FUNCDECL)) != TC_EOF) { 
     2891                if (tclass & TC_OPTERM) 
     2892                        continue; 
     2893 
     2894                seq = &tmp; 
     2895                if (tclass & TC_BEGIN) { 
     2896                        initseq = xzalloc(sizeof(chain)); 
     2897                        seq = initseq; 
     2898                        chain_group(); 
     2899                } else if (tclass & TC_FUNCDECL) { 
     2900                        next_token(TC_FUNCTION); 
     2901                        g_pos++; 
     2902                        f = newfunc(t_string); 
     2903                        f->type = AWKFUNC; 
     2904                        f->x.body.first = NULL; 
     2905                        f->nargs = 0; 
     2906                        while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { 
     2907                                v = findvar(ahash, t_string); 
     2908                                v->x.aidx = (f->nargs)++; 
     2909 
     2910                                if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) 
     2911                                        break; 
     2912                        } 
     2913                        seq = &(f->x.body); 
     2914                        chain_group(); 
     2915                        clear_array(ahash); 
     2916                } 
     2917        } 
     2918        if (initseq && initseq->first) 
     2919                tv = evaluate(initseq->first, tv); 
     2920        nvfree(tv); 
     2921} 
     2922 
     2923 
     2924/* include an awk file and run its BEGIN{} section */ 
     2925static xhash *includes = NULL; 
     2926static void include_file(const char *filename) 
     2927{ 
     2928        char *s; 
     2929        var *v; 
     2930        int oldlnr = g_lineno; 
     2931        const char *oldprg = g_progname; 
     2932 
     2933        if (!includes) 
     2934                includes = hash_init(); 
     2935 
     2936        /* find out if the file has been included already */ 
     2937        v = findvar(includes, filename); 
     2938        if (istrue(v)) 
     2939                return; 
     2940        setvar_s(v, "1"); 
     2941 
     2942        /* read include file */ 
     2943        s = get_file(filename); 
     2944        if (!s) { 
     2945                fprintf(stderr, "Could not open file.\n"); 
     2946                return; 
     2947        } 
     2948        g_lineno = 1; 
     2949        g_progname = xstrdup(filename); 
     2950        parse_include(s+1); 
     2951        free(s); 
     2952        g_lineno = oldlnr; 
     2953        g_progname = oldprg; 
     2954} 
     2955 
     2956static var *include(var *res, var *args, int nargs) 
     2957{ 
     2958        const char *s; 
     2959 
     2960        nargs = nargs; /* shut up, gcc */ 
     2961        s = getvar_s(args); 
     2962        if (s && (strlen(s) > 0)) 
     2963                include_file(s); 
     2964 
     2965        return res; 
     2966} 
     2967 
     2968/* registers a global c function for the awk interpreter */ 
     2969static void register_cfunc(const char *name, awk_cfunc cfunc, int nargs) 
     2970{ 
     2971        func *f; 
     2972 
     2973        f = newfunc(name); 
     2974        f->type = CFUNC; 
     2975        f->x.cfunc = cfunc; 
     2976        f->nargs = nargs; 
     2977} 
     2978 
    28322979int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 
    28332980int awk_main(int argc, char **argv) 
    28342981{ 
    int awk_main(int argc, char **argv) 
    28943041                        *s1 = '='; 
    28953042                } 
    28963043        } 
     3044 
     3045        register_cfunc("include", include, 1); 
     3046 
    28973047        opt_complementary = "v::f::"; /* -v and -f can occur multiple times */ 
    28983048        opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, &opt_W); 
    28993049        argv += optind; 
Note: See TracBrowser for help on using the repository browser.