📄 expand.c
字号:
/* * Copyright (c) 1997-2003 Erez Zadok * Copyright (c) 2001-2003 Stony Brook University * Copyright (c) 1997-2000 Columbia University * * For specific licensing information, see the COPYING file distributed with * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. * * This Copyright notice must be kept intact and distributed with all * fistgen sources INCLUDING sources generated by fistgen. *//* * expand.c: expand FIST_ variables * Fistgen sources. */#ifdef HAVE_CONFIG_H# include <config.h>#endif /* HAVE_CONFIG_H *//* forward definitions */static void expand_mod_src(char *dummy, void *data);static void expand_mod_hdr(char *dummy, void *data);static void expand_aux_src(char *dummy, void *data);static void expand_user_bins(char *dummy, void *data);static void expand_ubin_rules(char *dummy, void *data);static void expand_vfs_fields(char *dummy, void *data);static void expand_ioctl_defs(char *dummy, void *data);static void expand_ioctl_ecls(char *dummy, void *data);static void expand_auto_generated_externs(char *dummy, void *data);static void expand_add_mk(char *dummy, void *data);/* fword expansion functions */static fword_exp_fxn_t fword_exp_fxns[] = { {"MOD_SRC", expand_mod_src}, {"MOD_HDR", expand_mod_hdr}, {"AUX_SRC", expand_aux_src}, {"USER_BINS", expand_user_bins}, {"UBIN_RULES", expand_ubin_rules}, {"VFS_FIELDS", expand_vfs_fields}, {"IOCTL_DEFS", expand_ioctl_defs}, {"IOCTL_ECLS", expand_ioctl_ecls}, {"AUTO_GENERATED_EXTERNS", expand_auto_generated_externs}, {"ADDMK", expand_add_mk}, {NULL, NULL}};/* * Generate code for a given FIST_* word (fword) */voidexpand_fword(const char *fword){ char *cp; fword_exp_fxn_t *efp; int i; /* skip past "FIST_" */ cp = strchr(fword, '_'); cp++; /* check for special fist tags */ for (efp = fword_exp_fxns; efp->name; efp++) { if (STREQ(cp, efp->name)) { (efp->func)(NULL, NULL); return; } } /* * Check for fist precall/call/postcall tags. * For example: the tags FIST_OP_LOOKUP_POSTCALL will be replaced * with the code for %op:lookup:postcall. * If this tag can be a valid FIST_CALLSET_OPTYPE_PART tag, and there is * no code for it, then replace it with nothing (i.e., remove it from * template code). */ if (fist_validate_rule_tag(cp)) { for (i=0; i<fist_rules.fr_num_rules; i++) { if (STREQ(cp, fist_rules.fr_tag[i])) { wyy_echo(fist_rules.fr_code[i]->buf); return; } } /* if got here, there is no replacement: replace with NULL (remove) */ return; } /* * Nothing matched. * Any unknown FIST word should be printed verbatim. */ wyy_echo(fword);}/* * expand to list of module sources */static voidexpand_mod_src(char *dummy, void *data){ int i = fist_globals.fg_num_msources; char *cp; if (i < 1) { /* expand to nothing */ return; } for (i=0; i<fist_globals.fg_num_msources; ++i) { cp = fist_globals.fg_msources[i]; wyy_echo(cp); wyy_echo(" "); /* add space */ }}/* * expand to list of module headers */static voidexpand_mod_hdr(char *dummy, void *data){ int i = fist_globals.fg_num_mheaders; char *cp; if (i < 1) { /* expand to nothing */ return; } for (i=0; i<fist_globals.fg_num_mheaders; ++i) { cp = fist_globals.fg_mheaders[i]; wyy_echo(cp); wyy_echo(" "); /* add space */ }}/* * expand to list of auxiliary sources, for example those that contain * wrapfs_read_file and wrapfs_write_file, needed for fistGetFileData and * fistSetFileData, respectively. */static voidexpand_aux_src(char *dummy, void *data){ if (fist_globals.fg_num_fileformats > 0 || fist_globals.fg_filter & FF_FILTER_SCA || need_aux_sources) wyy_echo("aux.c"); /* if we chose "filter data/src attach", add mmap.c */ if (fist_globals.fg_filter & (FF_FILTER_DATA|FF_FILTER_SCA)) wyy_echo(" mmap.c"); /* if we chose "mntstyle attach", add attach.c */ if (fist_globals.fg_mntstyle & FF_MNTSTYLE_ATTACH) wyy_echo(" attach.c"); return; /* exapnd to nothing */}/* * expand to list of user binaries */static voidexpand_user_bins(char *dummy, void *data){ int i = fist_globals.fg_num_usources; int len; char buf[MAXPATHLEN], *cp; /* check if need to compile SCA binaries */ if (fist_globals.fg_filter & FF_FILTER_SCA) { wyy_echo("sca_list_idx sca_mk_idx sca_read sca_write "); } if (i < 1) { return; } for (i=0; i<fist_globals.fg_num_usources; ++i) { cp = fist_globals.fg_usources[i]; len = strlen(cp); if (STREQ(&cp[len-2], ".c")) { strcpy(buf, cp); buf[len-2] = '\0'; wyy_echo(buf); wyy_echo(" "); /* add space */ } }}/* * expand to list of user binaries Makefile rules */static voidexpand_ubin_rules(char *dummy, void *data){ int i = fist_globals.fg_num_usources; int len; char buf[MAXPATHLEN], out[MAX_BUF_LEN], *cp; char ucbuf[MAXPATHLEN]; if (i < 1) { /* expand to nothing */ return; } for (i=0; i<fist_globals.fg_num_usources; ++i) { cp = fist_globals.fg_usources[i]; len = strlen(cp); if (STREQ(&cp[len-2], ".c")) { strcpy(buf, cp); buf[len-2] = '\0'; strcpy(ucbuf, buf); uppercase_string(ucbuf);#ifdef __freebsd__ sprintf(out,"%s: %s.c ${%s_SRCS} ${CC} -o $@ $? ${UCFLAGS} ${%s_OBJS}", buf, buf, ucbuf, ucbuf);#else /* Not __freebsd__ */ sprintf(out,"%s: %s.c ${%s_SRCS} ${CC} -o $@ $^ ${UCFLAGS} ${%s_OBJS}", buf, buf, ucbuf, ucbuf);#endif /* Not __freebsd__ */ wyy_echo(out); } }}/* * expand to additional fields to add to struct vfs/super_block */static voidexpand_vfs_fields(char *dummy, void *data){ bdt_t *bdt = fist_globals.fg_pervfs; if (!bdt) /* if no fields, replace with nothing */ return; while (bdt) { wyy_echo(bdt->full_line); bdt = bdt->next; }}/* * expand to definitions of ioctls */static voidexpand_ioctl_defs(char *dummy, void *data){ int num = fist_globals.fg_num_ioctls; int i; char buf[MAX_BUF_LEN], *ioctlname; char *itstr; /* ioctl type string */ bdt_t *bdt; if (num == 0) /* if no ioctls, replace with nothing */ return; for (i = 0; i < num; i++) { ioctlname = fist_globals.fg_ioctl_name[i]; /* special case: ioctl that exchanges no info b/t user and kernel */ if (fist_globals.fg_ioctl_type[i] == FF_IOCTL_NONE) { sprintf(buf, "#define FIST_IOCTL_%s\t_IO(0x15, %d)\n", ioctlname, 10 + i); wyy_echo(buf); continue; } /* print structure for the ioctl */ sprintf(buf, "struct _fist_ioctl_%s {\n", ioctlname); wyy_echo(buf); bdt = fist_globals.fg_ioctl[i]; while (bdt) { wyy_echo(bdt->full_line); bdt = bdt->next; } wyy_echo("};\n"); /* print #define line for the ioctl */ switch (fist_globals.fg_ioctl_type[i]) { case FF_IOCTL_BOTH: itstr = "WR"; break; case FF_IOCTL_FROMUSER: itstr = "W"; break; case FF_IOCTL_TOUSER: itstr = "R"; break; case FF_IOCTL_NONE: default: itstr = ""; break; } sprintf(buf, "#define FIST_IOCTL_%s\t_IO%s(0x15, %d, struct _fist_ioctl_%s)\n", ioctlname, itstr, 10 + i, ioctlname); wyy_echo(buf); }}/* * print expanded code lines (ECLs) of ioctls, but only fist-defined ioctls. */static voidexpand_ioctl_ecls(char *dummy, void *data){ int i; char buf[MAX_BUF_LEN]; /* only print fist-defined ioctls */ for (i=0; i<fist_rules.fr_num_rules; i++) { if (!STREQ(fist_rules.fr_optype[i], "ioctl")) continue; if (fist_validate_rule_part(fist_rules.fr_part[i])) continue; sprintf(buf, " case FIST_IOCTL_%s:\n%s\n break;\n", fist_rules.fr_part[i], fist_rules.fr_code[i]->buf); wyy_echo(buf); }}/* * expand to extern definitions of auto-generated functions */static voidexpand_auto_generated_externs(char *dummy, void *data){ if (auto_generated_externs.buf) { wyy_echo("\n/* auto-generated externs */\n"); wyy_echo(auto_generated_externs.buf); }}/* * expand additional makefile */static voidexpand_add_mk(char *dummy, void *data){ int in_fd, i; char buf[MAX_BUF_LEN+1]; if (!fist_globals.fg_addmk) return; /* expand to nothing */ in_fd = open(fist_globals.fg_addmk, O_RDONLY); if (in_fd < 0) { perror(fist_globals.fg_addmk); exit(1); } while ((i = read(in_fd, buf, MAX_BUF_LEN)) > 0) { buf[i] = '\0'; wyy_echo(buf); } if (i < 0) { perror(fist_globals.fg_addmk); exit(1); } close(in_fd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -