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

Last change on this file since 26738 was 26738, checked in by nbd, 5 years ago

busybox: refresh patches

File size: 4.8 KB
  • editors/awk.c

    a b  
     1 
    12/* vi: set sw=4 ts=4: */ 
    23/* 
    34 * awk implementation for busybox 
    typedef struct chain_s { 
    7475} chain; 
    7576 
    7677/* Function */ 
     78typedef var *(*awk_cfunc)(var *res, var *args, int nargs); 
    7779typedef struct func_s { 
    7880        unsigned nargs; 
     81        enum { AWKFUNC, CFUNC } type; 
     82        union { 
     83                awk_cfunc cfunc; 
    7984        struct chain_s body; 
     85        } x; 
    8086} func; 
    8187 
    8288/* I/O stream */ 
    static void parse_program(char *p) 
    14661472                        next_token(TC_FUNCTION); 
    14671473                        g_pos++; 
    14681474                        f = newfunc(t_string); 
    1469                         f->body.first = NULL; 
     1475                        f->type = AWKFUNC; 
     1476                        f->x.body.first = NULL; 
    14701477                        f->nargs = 0; 
    14711478                        while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { 
    14721479                                v = findvar(ahash, t_string); 
    static void parse_program(char *p) 
    14751482                                if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) 
    14761483                                        break; 
    14771484                        } 
    1478                         seq = &f->body; 
     1485                        seq = &f->x.body; 
    14791486                        chain_group(); 
    14801487                        clear_array(ahash); 
    14811488 
    static var *evaluate(node *op, var *res) 
    25732580                        var *vbeg, *v; 
    25742581                        const char *sv_progname; 
    25752582 
    2576                         if (!op->r.f->body.first) 
     2583                        if ((op->r.f->type == AWKFUNC) && 
     2584                                !op->r.f->x.body.first) 
    25772585                                syntax_error(EMSG_UNDEF_FUNC); 
    25782586 
    25792587                        vbeg = v = nvalloc(op->r.f->nargs + 1); 
    static var *evaluate(node *op, var *res) 
    25902598                        fnargs = vbeg; 
    25912599                        sv_progname = g_progname; 
    25922600 
    2593                         res = evaluate(op->r.f->body.first, res); 
     2601                        if (op->r.f->type == AWKFUNC) 
     2602                                res = evaluate(op->r.f->x.body.first, res); 
     2603                        else if (op->r.f->type == CFUNC) 
     2604                                res = op->r.f->x.cfunc(res, fnargs, op->r.f->nargs); 
    25942605 
    25952606                        g_progname = sv_progname; 
    25962607                        nvfree(fnargs); 
    static rstream *next_input_file(void) 
    29842995#undef files_happen 
    29852996} 
    29862997 
     2998/* read the contents of an entire file */ 
     2999static char *get_file(const char *fname) 
     3000{ 
     3001        FILE *F; 
     3002        char *s = NULL; 
     3003        int i, j, flen; 
     3004 
     3005        F = fopen(fname, "r"); 
     3006        if (!F) { 
     3007                return NULL; 
     3008        } 
     3009 
     3010        if (fseek(F, 0, SEEK_END) == 0) { 
     3011                flen = ftell(F); 
     3012                s = (char *)xmalloc(flen+4); 
     3013                fseek(F, 0, SEEK_SET); 
     3014                i = 1 + fread(s+1, 1, flen, F); 
     3015        } else { 
     3016                for (i=j=1; j>0; i+=j) { 
     3017                        s = (char *)xrealloc(s, i+4096); 
     3018                        j = fread(s+i, 1, 4094, F); 
     3019                } 
     3020        } 
     3021 
     3022        s[i] = '\0'; 
     3023        fclose(F); 
     3024        return s; 
     3025} 
     3026 
     3027 
     3028/* parse_include(): 
     3029 * 
     3030 * taken from parse_program from awk.c 
     3031 * END{} is not parsed here, and BEGIN{} is executed immediately 
     3032 */ 
     3033static void parse_include(char *p) 
     3034{ 
     3035        uint32_t tclass; 
     3036        chain *initseq = NULL; 
     3037        chain tmp; 
     3038        func *f; 
     3039        var *v, *tv; 
     3040 
     3041        tv = nvalloc(1); 
     3042        memset(&tmp, 0, sizeof(tmp)); 
     3043        g_pos = p; 
     3044        t_lineno = 1; 
     3045        while ((tclass = next_token(TC_EOF | TC_OPSEQ | 
     3046                                TC_OPTERM | TC_BEGIN | TC_FUNCDECL)) != TC_EOF) { 
     3047                if (tclass & TC_OPTERM) 
     3048                        continue; 
     3049 
     3050                seq = &tmp; 
     3051                if (tclass & TC_BEGIN) { 
     3052                        initseq = xzalloc(sizeof(chain)); 
     3053                        seq = initseq; 
     3054                        chain_group(); 
     3055                } else if (tclass & TC_FUNCDECL) { 
     3056                        next_token(TC_FUNCTION); 
     3057                        g_pos++; 
     3058                        f = newfunc(t_string); 
     3059                        f->type = AWKFUNC; 
     3060                        f->x.body.first = NULL; 
     3061                        f->nargs = 0; 
     3062                        while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { 
     3063                                v = findvar(ahash, t_string); 
     3064                                v->x.aidx = (f->nargs)++; 
     3065 
     3066                                if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) 
     3067                                        break; 
     3068                        } 
     3069                        seq = &(f->x.body); 
     3070                        chain_group(); 
     3071                        clear_array(ahash); 
     3072                } 
     3073        } 
     3074        if (initseq && initseq->first) 
     3075                tv = evaluate(initseq->first, tv); 
     3076        nvfree(tv); 
     3077} 
     3078 
     3079 
     3080/* include an awk file and run its BEGIN{} section */ 
     3081static xhash *includes = NULL; 
     3082static void include_file(const char *filename) 
     3083{ 
     3084        char *s; 
     3085        var *v; 
     3086        int oldlnr = g_lineno; 
     3087        const char *oldprg = g_progname; 
     3088 
     3089        if (!includes) 
     3090                includes = hash_init(); 
     3091 
     3092        /* find out if the file has been included already */ 
     3093        v = findvar(includes, filename); 
     3094        if (istrue(v)) 
     3095                return; 
     3096        setvar_s(v, "1"); 
     3097 
     3098        /* read include file */ 
     3099        s = get_file(filename); 
     3100        if (!s) { 
     3101                fprintf(stderr, "Could not open file.\n"); 
     3102                return; 
     3103        } 
     3104        g_lineno = 1; 
     3105        g_progname = xstrdup(filename); 
     3106        parse_include(s+1); 
     3107        free(s); 
     3108        g_lineno = oldlnr; 
     3109        g_progname = oldprg; 
     3110} 
     3111 
     3112static var *include(var *res, var *args, int nargs) 
     3113{ 
     3114        const char *s; 
     3115 
     3116        nargs = nargs; /* shut up, gcc */ 
     3117        s = getvar_s(args); 
     3118        if (s && (strlen(s) > 0)) 
     3119                include_file(s); 
     3120 
     3121        return res; 
     3122} 
     3123 
     3124/* registers a global c function for the awk interpreter */ 
     3125static void register_cfunc(const char *name, awk_cfunc cfunc, int nargs) 
     3126{ 
     3127        func *f; 
     3128 
     3129        f = newfunc(name); 
     3130        f->type = CFUNC; 
     3131        f->x.cfunc = cfunc; 
     3132        f->nargs = nargs; 
     3133} 
     3134 
    29873135int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 
    29883136int awk_main(int argc, char **argv) 
    29893137{ 
    int awk_main(int argc, char **argv) 
    30493197                        *s1 = '='; 
    30503198                } 
    30513199        } 
     3200 
     3201        register_cfunc("include", include, 1); 
     3202 
    30523203        opt_complementary = "v::f::"; /* -v and -f can occur multiple times */ 
    30533204        opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, &opt_W); 
    30543205        argv += optind; 
Note: See TracBrowser for help on using the repository browser.