📄 code.c
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2005,2007 Oracle. All rights reserved. * * $Id: code.c,v 1.14 2007/05/17 15:15:13 bostic Exp $ */#include "csv.h"typedef struct { char *name; /* Field name */ char *upper; /* Field name in upper-case */ datatype type; /* Data type */ int indx; /* Index */} FIELD;int code_source(void);int code_header(void);int desc_dump(void);int desc_load(void);char *type_to_string(datatype);int usage(void);/* * Globals */FILE *cfp; /* C source file */FILE *hfp; /* C source file */char *progname; /* Program name */int verbose; /* Verbose flag */u_int field_cnt; /* Count of fields */FIELD *fields; /* Field list */intmain(int argc, char *argv[]){ int ch; char *cfile, *hfile; /* Initialize globals. */ if ((progname = strrchr(argv[0], '/')) == NULL) progname = argv[0]; else ++progname; /* Initialize arguments. */ cfile = "csv_local.c"; /* Default header/source files */ hfile = "csv_local.h"; /* Process arguments. */ while ((ch = getopt(argc, argv, "c:f:h:v")) != EOF) switch (ch) { case 'c': cfile = optarg; break; case 'f': if (freopen(optarg, "r", stdin) == NULL) { fprintf(stderr, "%s: %s\n", optarg, strerror(errno)); return (EXIT_FAILURE); } break; case 'h': hfile = optarg; break; case 'v': ++verbose; break; case '?': default: return (usage()); } argc -= optind; argv += optind; if (*argv != NULL) return (usage()); /* Load records from the input file. */ if (desc_load()) return (EXIT_FAILURE); /* Dump records for debugging. */ if (verbose && desc_dump()) return (EXIT_FAILURE); /* Open output files. */ if ((cfp = fopen(cfile, "w")) == NULL) { fprintf(stderr, "%s: %s: %s\n", progname, cfile, strerror(errno)); return (EXIT_FAILURE); } if ((hfp = fopen(hfile, "w")) == NULL) { fprintf(stderr, "%s: %s: %s\n", progname, hfile, strerror(errno)); return (EXIT_FAILURE); } /* Build the source and header files. */ if (code_header()) return (EXIT_FAILURE); if (code_source()) return (EXIT_FAILURE); return (EXIT_SUCCESS);}/* * desc_load -- * Load a description file. */intdesc_load(){ u_int field_alloc; int version; char *p, *t, save_ch, buf[256]; field_alloc = version = 0; while (fgets(buf, sizeof(buf), stdin) != NULL) { if ((p = strchr(buf, '\n')) == NULL) { fprintf(stderr, "%s: input line too long\n", progname); return (1); } *p = '\0'; /* Skip leading whitespace. */ for (p = buf; isspace(*p); ++p) ; /* Skip empty lines or lines beginning with '#'. */ if (*p == '\0' || *p == '#') continue; /* Get a version. */ if (!version) { if (strncasecmp( p, "version", sizeof("version") - 1) == 0) { version = 1; continue; } fprintf(stderr, "%s: expected \"version\" line\n", progname); return (1); } /* * Skip block close -- not currently useful, but when this * code supports versioned descriptions, it will matter. */ if (*p == '}') { version = 0; continue; } /* Allocate a new field structure as necessary. */ if (field_cnt == field_alloc && (fields = realloc(fields, field_alloc += 100)) == NULL) { fprintf(stderr, "%s: %s\n", progname, strerror(errno)); return (1); } /* Find the end of the field name. */ for (t = p; *t != '\0' && !isspace(*t); ++t) ; save_ch = *t; *t = '\0'; if ((fields[field_cnt].name = strdup(p)) == NULL || (fields[field_cnt].upper = strdup(p)) == NULL) { fprintf(stderr, "%s: %s\n", progname, strerror(errno)); return (1); } *t = save_ch; p = t; fields[field_cnt].indx = 0; fields[field_cnt].type = NOTSET; for (;;) { /* Skip to the next field, if any. */ for (; *p != '\0' && isspace(*p); ++p) ; if (*p == '\0') break; /* Find the end of the field. */ for (t = p; *t != '\0' && !isspace(*t); ++t) ; save_ch = *t; *t = '\0'; if (strcasecmp(p, "double") == 0) fields[field_cnt].type = DOUBLE; else if (strcasecmp(p, "index") == 0) fields[field_cnt].indx = 1; else if (strcasecmp(p, "string") == 0) fields[field_cnt].type = STRING; else if (strcasecmp(p, "ulong") == 0) fields[field_cnt].type = ULONG; else { fprintf(stderr, "%s: unknown keyword: %s\n", progname, p); return (1); } *t = save_ch; p = t; } /* Create a copy of the field name that's upper-case. */ for (p = fields[field_cnt].upper; *p != '\0'; ++p) if (islower(*p)) *p = (char)toupper(*p); ++field_cnt; } if (ferror(stdin)) { fprintf(stderr, "%s: stdin: %s\n", progname, strerror(errno)); return (1); } return (0);}/* * desc_dump -- * Dump a set of FIELD structures. */intdesc_dump(){ FIELD *f; u_int i; for (f = fields, i = 0; i < field_cnt; ++i, ++f) { fprintf(stderr, "field {%s}: (", f->name); switch (f->type) { case NOTSET: fprintf(stderr, "ignored"); break; case DOUBLE: fprintf(stderr, "double"); break; case STRING: fprintf(stderr, "string"); break; case ULONG: fprintf(stderr, "ulong"); break; } if (f->indx) fprintf(stderr, ", indexed"); fprintf(stderr, ")\n"); } return (0);}/* * code_header -- * Print out the C #include file. */intcode_header(){ FIELD *f; u_int i; fprintf(hfp, "/*\n"); fprintf(hfp, " * DO NOT EDIT: automatically built by %s.\n", progname); fprintf(hfp, " *\n"); fprintf(hfp, " * Record structure.\n"); fprintf(hfp, " */\n"); fprintf(hfp, "typedef struct __DbRecord {\n"); fprintf(hfp, "\tu_int32_t\t recno;\t\t/* Record number */\n"); fprintf(hfp, "\n"); fprintf(hfp, "\t/*\n"); fprintf(hfp, "\t * Management fields\n"); fprintf(hfp, "\t */\n"); fprintf(hfp, "\tvoid\t\t*raw;\t\t/* Memory returned by DB */\n"); fprintf(hfp, "\tu_char\t\t*record;\t/* Raw record */\n"); fprintf(hfp, "\tsize_t\t\t record_len;\t/* Raw record length */\n\n"); fprintf(hfp, "\tu_int32_t\t field_count;\t/* Field count */\n"); fprintf(hfp, "\tu_int32_t\t version;\t/* Record version */\n\n"); fprintf(hfp, "\tu_int32_t\t*offset;\t/* Offset table */\n"); fprintf(hfp, "\n"); fprintf(hfp, "\t/*\n"); fprintf(hfp, "\t * Indexed fields\n"); fprintf(hfp, "\t */\n"); for (f = fields, i = 0; i < field_cnt; ++i, ++f) { if (f->type == NOTSET) continue; if (i != 0) fprintf(hfp, "\n"); fprintf(hfp, "#define CSV_INDX_%s\t%d\n", f->upper, i + 1); switch (f->type) { case NOTSET: /* NOTREACHED */ abort(); break; case DOUBLE: fprintf(hfp, "\tdouble\t\t %s;\n", f->name); break; case STRING: fprintf(hfp, "\tchar\t\t*%s;\n", f->name); break; case ULONG: fprintf(hfp, "\tu_long\t\t %s;\n", f->name); break; } } fprintf(hfp, "} DbRecord;\n"); return (0);}/* * code_source -- * Print out the C structure initialization. */intcode_source(){ FIELD *f; u_int i; fprintf(cfp, "/*\n"); fprintf(cfp, " * DO NOT EDIT: automatically built by %s.\n", progname); fprintf(cfp, " *\n"); fprintf(cfp, " * Initialized record structure.\n"); fprintf(cfp, " */\n"); fprintf(cfp, "\n"); fprintf(cfp, "#include \"csv.h\"\n"); fprintf(cfp, "#include \"csv_local.h\"\n"); fprintf(cfp, "\n"); fprintf(cfp, "DbRecord DbRecord_base = {\n"); fprintf(cfp, "\t0,\t\t/* Record number */\n"); fprintf(cfp, "\tNULL,\t\t/* Memory returned by DB */\n"); fprintf(cfp, "\tNULL,\t\t/* Raw record */\n"); fprintf(cfp, "\t0,\t\t/* Raw record length */\n"); fprintf(cfp, "\t%d,\t\t/* Field count */\n", field_cnt); fprintf(cfp, "\t0,\t\t/* Record version */\n"); fprintf(cfp, "\tNULL,\t\t/* Offset table */\n"); fprintf(cfp, "\n"); for (f = fields, i = 0; i < field_cnt; ++i, ++f) { if (f->type == NOTSET) continue; switch (f->type) { case NOTSET: abort(); /* NOTREACHED */ break; case DOUBLE: case ULONG: fprintf(cfp, "\t0,\t\t/* %s */\n", f->name); break; case STRING: fprintf(cfp, "\tNULL,\t\t/* %s */\n", f->name); break; } } fprintf(cfp, "};\n"); fprintf(cfp, "\n"); fprintf(cfp, "DbField fieldlist[] = {\n"); for (f = fields, i = 0; i < field_cnt; ++i, ++f) { if (f->type == NOTSET) continue; fprintf(cfp, "\t{ \"%s\",", f->name); fprintf(cfp, " CSV_INDX_%s,", f->upper); fprintf(cfp, "\n\t %s,", type_to_string(f->type)); fprintf(cfp, " %d,", f->indx ? 1 : 0); fprintf(cfp, " NULL,"); fprintf(cfp, " FIELD_OFFSET(%s)},\n", f->name); } fprintf(cfp, "\t{NULL, 0, STRING, 0, NULL, 0}\n};\n"); return (0);}char *type_to_string(type) datatype type;{ switch (type) { case NOTSET: return ("NOTSET"); case DOUBLE: return ("DOUBLE"); case STRING: return ("STRING"); case ULONG: return ("ULONG"); } abort(); /* NOTREACHED */}intusage(){ (void)fprintf(stderr, "usage: %s [-v] [-c source-file] [-f input] [-h header-file]\n", progname); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -