0ffa676110 2019-12-02 1: #include <sys/stat.h>
0ffa676110 2019-12-02 2: #include <stdlib.h>
20809b08ce 2019-12-01 3: #include <string.h>
0ffa676110 2019-12-02 4: #include <dirent.h>
20809b08ce 2019-12-01 5: #include <stdio.h>
20809b08ce 2019-12-01 6: #include <ctype.h>
0ffa676110 2019-12-02 7: #include <fcntl.h>
20809b08ce 2019-12-01 8:
20809b08ce 2019-12-01 9: struct options {
20809b08ce 2019-12-01 10: char *name;
20809b08ce 2019-12-01 11: char *directory;
0ffa676110 2019-12-02 12: };
0ffa676110 2019-12-02 13:
0ffa676110 2019-12-02 14: struct xvfs_state {
0ffa676110 2019-12-02 15: char **children;
0ffa676110 2019-12-02 16: unsigned long child_count;
0ffa676110 2019-12-02 17: unsigned long child_len;
0ffa676110 2019-12-02 18: int bucket_count;
0ffa676110 2019-12-02 19: int max_index;
20809b08ce 2019-12-01 20: };
20809b08ce 2019-12-01 21:
20809b08ce 2019-12-01 22: enum xvfs_minirivet_mode {
20809b08ce 2019-12-01 23: XVFS_MINIRIVET_MODE_COPY,
20809b08ce 2019-12-01 24: XVFS_MINIRIVET_MODE_TCL,
20809b08ce 2019-12-01 25: XVFS_MINIRIVET_MODE_TCL_PRINT
20809b08ce 2019-12-01 26: };
20809b08ce 2019-12-01 27:
0ffa676110 2019-12-02 28: /*
0ffa676110 2019-12-02 29: * adler32() function from zlib 1.1.4 and under the same license
0ffa676110 2019-12-02 30: */
0ffa676110 2019-12-02 31: static unsigned long adler32(unsigned long adler, const unsigned char *buf, unsigned int len) {
0ffa676110 2019-12-02 32: const int len_max = 5552;
0ffa676110 2019-12-02 33: const unsigned long base = 65521;
0ffa676110 2019-12-02 34: unsigned long s1 = adler & 0xffff;
0ffa676110 2019-12-02 35: unsigned long s2 = (adler >> 16) & 0xffff;
0ffa676110 2019-12-02 36: int k, i;
0ffa676110 2019-12-02 37:
0ffa676110 2019-12-02 38: if (buf == NULL) {
0ffa676110 2019-12-02 39: return(1UL);
0ffa676110 2019-12-02 40: }
0ffa676110 2019-12-02 41:
0ffa676110 2019-12-02 42: while (len > 0) {
0ffa676110 2019-12-02 43: k = len < len_max ? len : len_max;
0ffa676110 2019-12-02 44: len -= k;
0ffa676110 2019-12-02 45:
0ffa676110 2019-12-02 46: while (k >= 16) {
0ffa676110 2019-12-02 47: for (i = 0; i < 16; i++) {
0ffa676110 2019-12-02 48: s2 += buf[i];
0ffa676110 2019-12-02 49: }
0ffa676110 2019-12-02 50: s1 = buf[15];
0ffa676110 2019-12-02 51:
0ffa676110 2019-12-02 52: buf += 16;
0ffa676110 2019-12-02 53: k -= 16;
0ffa676110 2019-12-02 54: }
0ffa676110 2019-12-02 55:
0ffa676110 2019-12-02 56: if (k != 0) {
0ffa676110 2019-12-02 57: do {
0ffa676110 2019-12-02 58: s1 += *buf++;
0ffa676110 2019-12-02 59: s2 += s1;
0ffa676110 2019-12-02 60: } while (--k);
0ffa676110 2019-12-02 61: }
0ffa676110 2019-12-02 62:
0ffa676110 2019-12-02 63: s1 %= base;
0ffa676110 2019-12-02 64: s2 %= base;
0ffa676110 2019-12-02 65: }
0ffa676110 2019-12-02 66:
0ffa676110 2019-12-02 67: return((s2 << 16) | s1);
0ffa676110 2019-12-02 68: }
0ffa676110 2019-12-02 69:
0ffa676110 2019-12-02 70: /*
0ffa676110 2019-12-02 71: * Handle XVFS Rivet template file substitution
0ffa676110 2019-12-02 72: */
0ffa676110 2019-12-02 73: static void parse_xvfs_minirivet_file(FILE *outfp, const char * const external_file_name, const char * const internal_file_name) {
0ffa676110 2019-12-02 74: FILE *fp;
0ffa676110 2019-12-02 75: unsigned long file_size;
0ffa676110 2019-12-02 76: unsigned char buf[10];
0ffa676110 2019-12-02 77: size_t item_count;
0ffa676110 2019-12-02 78: int idx;
0ffa676110 2019-12-02 79:
0ffa676110 2019-12-02 80: fp = fopen(external_file_name, "rb");
0ffa676110 2019-12-02 81: if (!fp) {
0ffa676110 2019-12-02 82: return;
0ffa676110 2019-12-02 83: }
0ffa676110 2019-12-02 84:
0ffa676110 2019-12-02 85: fprintf(outfp, "\t{\n");
0ffa676110 2019-12-02 86: fprintf(outfp, "\t\t.name = \"%s\",\n", internal_file_name);
0ffa676110 2019-12-02 87: fprintf(outfp, "\t\t.type = XVFS_FILE_TYPE_REG,\n");
0ffa676110 2019-12-02 88: fprintf(outfp, "\t\t.data.fileContents = (const unsigned char *) \"");
0ffa676110 2019-12-02 89:
0ffa676110 2019-12-02 90: file_size = 0;
0ffa676110 2019-12-02 91: while (1) {
0ffa676110 2019-12-02 92: item_count = fread(&buf, 1, sizeof(buf), fp);
0ffa676110 2019-12-02 93: if (item_count <= 0) {
0ffa676110 2019-12-02 94: break;
0ffa676110 2019-12-02 95: }
0ffa676110 2019-12-02 96:
0ffa676110 2019-12-02 97: if (file_size != 0) {
0ffa676110 2019-12-02 98: fprintf(outfp, "\n\t\t\t\"");
0ffa676110 2019-12-02 99: }
0ffa676110 2019-12-02 100:
0ffa676110 2019-12-02 101: for (idx = 0; idx < item_count; idx++) {
0ffa676110 2019-12-02 102: fprintf(outfp, "\\x%02x", (int) buf[idx]);
0ffa676110 2019-12-02 103: }
0ffa676110 2019-12-02 104: fprintf(outfp, "\"");
0ffa676110 2019-12-02 105:
0ffa676110 2019-12-02 106: file_size += item_count;
0ffa676110 2019-12-02 107: }
0ffa676110 2019-12-02 108:
0ffa676110 2019-12-02 109: fclose(fp);
0ffa676110 2019-12-02 110:
0ffa676110 2019-12-02 111: fprintf(outfp, ",\n");
0ffa676110 2019-12-02 112: fprintf(outfp, "\t\t.size = %lu\n", file_size);
0ffa676110 2019-12-02 113: fprintf(outfp, "\t},\n");
0ffa676110 2019-12-02 114: }
0ffa676110 2019-12-02 115:
0ffa676110 2019-12-02 116: static void parse_xvfs_minirivet_directory(FILE *outfp, struct xvfs_state *xvfs_state, const char * const directory, const char * const prefix) {
0ffa676110 2019-12-02 117: const unsigned int max_path_len = 8192, max_children = 65536;
0ffa676110 2019-12-02 118: unsigned long child_idx, child_count;
0ffa676110 2019-12-02 119: DIR *dp;
0ffa676110 2019-12-02 120: struct dirent *file_info;
0ffa676110 2019-12-02 121: struct stat file_stat;
0ffa676110 2019-12-02 122: char *full_path_buf;
0ffa676110 2019-12-02 123: char *rel_path_buf;
0ffa676110 2019-12-02 124: char **children;
0ffa676110 2019-12-02 125: int stat_ret;
0ffa676110 2019-12-02 126: int snprintf_ret;
0ffa676110 2019-12-02 127:
0ffa676110 2019-12-02 128: dp = opendir(directory);
0ffa676110 2019-12-02 129: if (!dp) {
0ffa676110 2019-12-02 130: return;
0ffa676110 2019-12-02 131: }
0ffa676110 2019-12-02 132:
0ffa676110 2019-12-02 133: full_path_buf = malloc(max_path_len);
0ffa676110 2019-12-02 134: rel_path_buf = malloc(max_path_len);
0ffa676110 2019-12-02 135: children = malloc(sizeof(*children) * max_children);
0ffa676110 2019-12-02 136:
0ffa676110 2019-12-02 137: child_idx = 0;
0ffa676110 2019-12-02 138: while (1) {
0ffa676110 2019-12-02 139: file_info = readdir(dp);
0ffa676110 2019-12-02 140: if (!file_info) {
0ffa676110 2019-12-02 141: break;
0ffa676110 2019-12-02 142: }
0ffa676110 2019-12-02 143:
0ffa676110 2019-12-02 144: if (strcmp(file_info->d_name, ".") == 0) {
0ffa676110 2019-12-02 145: continue;
0ffa676110 2019-12-02 146: }
0ffa676110 2019-12-02 147:
0ffa676110 2019-12-02 148: if (strcmp(file_info->d_name, "..") == 0) {
0ffa676110 2019-12-02 149: continue;
0ffa676110 2019-12-02 150: }
0ffa676110 2019-12-02 151:
0ffa676110 2019-12-02 152: snprintf_ret = snprintf(full_path_buf, max_path_len, "%s/%s", directory, file_info->d_name);
0ffa676110 2019-12-02 153: if (snprintf_ret >= max_path_len) {
0ffa676110 2019-12-02 154: continue;
0ffa676110 2019-12-02 155: }
0ffa676110 2019-12-02 156:
0ffa676110 2019-12-02 157: snprintf_ret = snprintf(rel_path_buf, max_path_len, "%s%s%s",
0ffa676110 2019-12-02 158: prefix,
0ffa676110 2019-12-02 159: strcmp(prefix, "") == 0 ? "" : "/",
0ffa676110 2019-12-02 160: file_info->d_name
0ffa676110 2019-12-02 161: );
0ffa676110 2019-12-02 162: if (snprintf_ret >= max_path_len) {
0ffa676110 2019-12-02 163: continue;
0ffa676110 2019-12-02 164: }
0ffa676110 2019-12-02 165:
0ffa676110 2019-12-02 166: stat_ret = stat(full_path_buf, &file_stat);
0ffa676110 2019-12-02 167: if (stat_ret != 0) {
0ffa676110 2019-12-02 168: continue;
0ffa676110 2019-12-02 169: }
0ffa676110 2019-12-02 170:
0ffa676110 2019-12-02 171: children[child_idx] = strdup(file_info->d_name);
0ffa676110 2019-12-02 172: child_idx++;
0ffa676110 2019-12-02 173:
0ffa676110 2019-12-02 174: if (S_ISDIR(file_stat.st_mode)) {
0ffa676110 2019-12-02 175: parse_xvfs_minirivet_directory(outfp, xvfs_state, full_path_buf, rel_path_buf);
0ffa676110 2019-12-02 176: } else {
0ffa676110 2019-12-02 177: parse_xvfs_minirivet_file(outfp, full_path_buf, rel_path_buf);
0ffa676110 2019-12-02 178:
0ffa676110 2019-12-02 179: xvfs_state->children[xvfs_state->child_count] = strdup(rel_path_buf);
0ffa676110 2019-12-02 180: xvfs_state->child_count++;
0ffa676110 2019-12-02 181: }
0ffa676110 2019-12-02 182: }
0ffa676110 2019-12-02 183: free(full_path_buf);
0ffa676110 2019-12-02 184: free(rel_path_buf);
0ffa676110 2019-12-02 185:
0ffa676110 2019-12-02 186: child_count = child_idx;
0ffa676110 2019-12-02 187:
0ffa676110 2019-12-02 188: fprintf(outfp, "\t{\n");
0ffa676110 2019-12-02 189: fprintf(outfp, "\t\t.name = \"%s\",\n", prefix);
0ffa676110 2019-12-02 190: fprintf(outfp, "\t\t.type = XVFS_FILE_TYPE_DIR,\n");
0ffa676110 2019-12-02 191: fprintf(outfp, "\t\t.size = %lu,\n", child_count);
0ffa676110 2019-12-02 192: fprintf(outfp, "\t\t.data.dirChildren = (const char *[]) {");
0ffa676110 2019-12-02 193: for (child_idx = 0; child_idx < child_count; child_idx++) {
0ffa676110 2019-12-02 194: if (child_idx != 0) {
0ffa676110 2019-12-02 195: fprintf(outfp, ", ");
0ffa676110 2019-12-02 196: }
0ffa676110 2019-12-02 197:
0ffa676110 2019-12-02 198: fprintf(outfp, "\"%s\"", children[child_idx]);
0ffa676110 2019-12-02 199:
0ffa676110 2019-12-02 200: free(children[child_idx]);
0ffa676110 2019-12-02 201: }
0ffa676110 2019-12-02 202: fprintf(outfp, "}\n");
0ffa676110 2019-12-02 203:
0ffa676110 2019-12-02 204: free(children);
0ffa676110 2019-12-02 205:
0ffa676110 2019-12-02 206: fprintf(outfp, "\t},\n");
0ffa676110 2019-12-02 207:
0ffa676110 2019-12-02 208: xvfs_state->children[xvfs_state->child_count] = strdup(prefix);
0ffa676110 2019-12-02 209: xvfs_state->child_count++;
0ffa676110 2019-12-02 210:
0ffa676110 2019-12-02 211: closedir(dp);
0ffa676110 2019-12-02 212:
0ffa676110 2019-12-02 213: return;
0ffa676110 2019-12-02 214: }
0ffa676110 2019-12-02 215:
0ffa676110 2019-12-02 216: static void parse_xvfs_minirivet_hashtable_header(FILE *outfp, struct xvfs_state *xvfs_state) {
0ffa676110 2019-12-02 217: const int max_bucket_count = 30;
0ffa676110 2019-12-02 218: int bucket_count;
0ffa676110 2019-12-02 219: int idx1, idx2;
0ffa676110 2019-12-02 220: int check_hash;
0ffa676110 2019-12-02 221: int first_entry;
0ffa676110 2019-12-02 222:
0ffa676110 2019-12-02 223: if (xvfs_state->child_count > max_bucket_count) {
0ffa676110 2019-12-02 224: bucket_count = max_bucket_count;
0ffa676110 2019-12-02 225: } else {
0ffa676110 2019-12-02 226: bucket_count = xvfs_state->child_count;
0ffa676110 2019-12-02 227: }
0ffa676110 2019-12-02 228: xvfs_state->bucket_count = bucket_count;
0ffa676110 2019-12-02 229: xvfs_state->max_index = xvfs_state->child_count;
0ffa676110 2019-12-02 230:
0ffa676110 2019-12-02 231: fprintf(outfp, "\tlong pathIndex_idx;\n");
0ffa676110 2019-12-02 232: fprintf(outfp, "\tint pathIndex_hash;\n");
0ffa676110 2019-12-02 233:
0ffa676110 2019-12-02 234: /*
0ffa676110 2019-12-02 235: * XXX:TODO: Make this not O(n^2)
0ffa676110 2019-12-02 236: */
0ffa676110 2019-12-02 237: for (idx1 = 0; idx1 < bucket_count; idx1++) {
0ffa676110 2019-12-02 238: fprintf(outfp, "\tstatic const long pathIndex_hashTable_%i[] = {\n", idx1);
0ffa676110 2019-12-02 239: fprintf(outfp, "\t\t");
0ffa676110 2019-12-02 240: first_entry = 1;
0ffa676110 2019-12-02 241:
0ffa676110 2019-12-02 242: for (idx2 = 0; idx2 < xvfs_state->child_count; idx2++) {
1d38520446 2019-12-02 243: check_hash = adler32(0, (unsigned char *) xvfs_state->children[idx2], strlen(xvfs_state->children[idx2])) % bucket_count;
0ffa676110 2019-12-02 244: if (check_hash != idx1) {
0ffa676110 2019-12-02 245: continue;
0ffa676110 2019-12-02 246: }
0ffa676110 2019-12-02 247:
0ffa676110 2019-12-02 248: if (!first_entry) {
0ffa676110 2019-12-02 249: fprintf(outfp, ", ");
0ffa676110 2019-12-02 250: }
0ffa676110 2019-12-02 251: first_entry = 0;
0ffa676110 2019-12-02 252:
0ffa676110 2019-12-02 253: if (check_hash == idx1) {
0ffa676110 2019-12-02 254: fprintf(outfp, "%i", idx2);
0ffa676110 2019-12-02 255: }
0ffa676110 2019-12-02 256: }
0ffa676110 2019-12-02 257:
0ffa676110 2019-12-02 258: if (!first_entry) {
0ffa676110 2019-12-02 259: fprintf(outfp, ", ");
0ffa676110 2019-12-02 260: }
0ffa676110 2019-12-02 261: fprintf(outfp, "XVFS_NAME_LOOKUP_ERROR");
0ffa676110 2019-12-02 262:
0ffa676110 2019-12-02 263: fprintf(outfp, "\n");
0ffa676110 2019-12-02 264:
0ffa676110 2019-12-02 265: fprintf(outfp, "\t};\n");
0ffa676110 2019-12-02 266: }
c69f6f1b5a 2019-12-02 267:
c69f6f1b5a 2019-12-02 268: for (idx2 = 0; idx2 < xvfs_state->child_count; idx2++) {
c69f6f1b5a 2019-12-02 269: free(xvfs_state->children[idx2]);
c69f6f1b5a 2019-12-02 270: }
c69f6f1b5a 2019-12-02 271: free(xvfs_state->children);
0ffa676110 2019-12-02 272:
0ffa676110 2019-12-02 273: fprintf(outfp, "\tstatic const long * const pathIndex_hashTable[%i] = {\n", bucket_count);
0ffa676110 2019-12-02 274: for (idx1 = 0; idx1 < bucket_count; idx1++) {
0ffa676110 2019-12-02 275: fprintf(outfp, "\t\tpathIndex_hashTable_%i,\n", idx1);
0ffa676110 2019-12-02 276: }
0ffa676110 2019-12-02 277: fprintf(outfp, "\t};\n");
0ffa676110 2019-12-02 278: return;
0ffa676110 2019-12-02 279: }
0ffa676110 2019-12-02 280:
0ffa676110 2019-12-02 281: static void parse_xvfs_minirivet_hashtable_body(FILE *outfp, struct xvfs_state *xvfs_state) {
0ffa676110 2019-12-02 282: fprintf(outfp, "\tpathIndex_hash = Tcl_ZlibAdler32(0, (unsigned char *) path, pathLen) %% %i;\n", xvfs_state->bucket_count);
0ffa676110 2019-12-02 283: fprintf(outfp, "\tfor (pathIndex_idx = 0; pathIndex_idx < %i; pathIndex_idx++) {\n", xvfs_state->max_index);
0ffa676110 2019-12-02 284: fprintf(outfp, "\t\tpathIndex = pathIndex_hashTable[pathIndex_hash][pathIndex_idx];\n");
0ffa676110 2019-12-02 285: fprintf(outfp, "\t\tif (pathIndex == XVFS_NAME_LOOKUP_ERROR) {\n");
0ffa676110 2019-12-02 286: fprintf(outfp, "\t\t\tbreak;\n");
0ffa676110 2019-12-02 287: fprintf(outfp, "\t\t}\n");
0ffa676110 2019-12-02 288: fprintf(outfp, "\n");
0ffa676110 2019-12-02 289: fprintf(outfp, "\t\tif (strcmp(path, xvfs_example_data[pathIndex].name) == 0) {\n");
0ffa676110 2019-12-02 290: fprintf(outfp, "\t\t\treturn(pathIndex);\n");
0ffa676110 2019-12-02 291: fprintf(outfp, "\t\t}\n");
0ffa676110 2019-12-02 292: fprintf(outfp, "\t}\n");
0ffa676110 2019-12-02 293: return;
0ffa676110 2019-12-02 294: }
0ffa676110 2019-12-02 295:
0ffa676110 2019-12-02 296: static void parse_xvfs_minirivet_handle_tcl_print(FILE *outfp, const struct options * const options, struct xvfs_state *xvfs_state, char *command) {
0ffa676110 2019-12-02 297: char *buffer_p, *buffer_e;
0ffa676110 2019-12-02 298:
0ffa676110 2019-12-02 299: buffer_p = command;
0ffa676110 2019-12-02 300: while (*buffer_p && isspace(*buffer_p)) {
0ffa676110 2019-12-02 301: buffer_p++;
0ffa676110 2019-12-02 302: }
0ffa676110 2019-12-02 303:
0ffa676110 2019-12-02 304: buffer_e = buffer_p + strlen(buffer_p) - 1;
0ffa676110 2019-12-02 305: while (buffer_e >= buffer_p && isspace(*buffer_e)) {
0ffa676110 2019-12-02 306: *buffer_e = '\0';
0ffa676110 2019-12-02 307: buffer_e--;
0ffa676110 2019-12-02 308: }
0ffa676110 2019-12-02 309:
0ffa676110 2019-12-02 310: if (strcmp(buffer_p, "$::xvfs::fsName") == 0) {
0ffa676110 2019-12-02 311: fprintf(outfp, "%s", options->name);
0ffa676110 2019-12-02 312: } else if (strcmp(buffer_p, "$::xvfs::fileInfoStruct") == 0) {
0ffa676110 2019-12-02 313: fprintf(outfp, "static const struct xvfs_file_data xvfs_");
0ffa676110 2019-12-02 314: fprintf(outfp, "%s", options->name);
0ffa676110 2019-12-02 315: fprintf(outfp, "_data[] = {\n");
0ffa676110 2019-12-02 316: parse_xvfs_minirivet_directory(outfp, xvfs_state, options->directory, "");
0ffa676110 2019-12-02 317: fprintf(outfp, "};\n");
0ffa676110 2019-12-02 318: } else if (strcmp(buffer_p, "[zlib adler32 $::xvfs::fsName 0]") == 0) {
0ffa676110 2019-12-02 319: fprintf(outfp, "%lu", adler32(0, (unsigned char *) options->name, strlen(options->name)));
0ffa676110 2019-12-02 320: } else if (strcmp(buffer_p, "$hashTableHeader") == 0) {
0ffa676110 2019-12-02 321: parse_xvfs_minirivet_hashtable_header(outfp, xvfs_state);
0ffa676110 2019-12-02 322: } else if (strcmp(buffer_p, "[dict get $hashTable body]") == 0) {
0ffa676110 2019-12-02 323: parse_xvfs_minirivet_hashtable_body(outfp, xvfs_state);
0ffa676110 2019-12-02 324: } else {
0ffa676110 2019-12-02 325: fprintf(outfp, "@INVALID@%s@INVALID@", buffer_p);
0ffa676110 2019-12-02 326: }
0ffa676110 2019-12-02 327:
0ffa676110 2019-12-02 328: return;
0ffa676110 2019-12-02 329: }
0ffa676110 2019-12-02 330:
0ffa676110 2019-12-02 331: static int parse_xvfs_minirivet(FILE *outfp, const char * const file, const struct options * const options) {
0ffa676110 2019-12-02 332: struct xvfs_state xvfs_state;
0ffa676110 2019-12-02 333: FILE *fp;
0ffa676110 2019-12-02 334: int ch, ch_buf;
0ffa676110 2019-12-02 335: char tcl_buffer[8192], *tcl_buffer_p;
0ffa676110 2019-12-02 336: enum xvfs_minirivet_mode mode;
0ffa676110 2019-12-02 337:
0ffa676110 2019-12-02 338: fp = fopen(file, "r");
0ffa676110 2019-12-02 339: if (!fp) {
0ffa676110 2019-12-02 340: return(0);
0ffa676110 2019-12-02 341: }
0ffa676110 2019-12-02 342:
0ffa676110 2019-12-02 343: xvfs_state.child_count = 0;
0ffa676110 2019-12-02 344: xvfs_state.child_len = 65536;
0ffa676110 2019-12-02 345: xvfs_state.children = malloc(sizeof(*xvfs_state.children) * xvfs_state.child_len);
0ffa676110 2019-12-02 346:
0ffa676110 2019-12-02 347: #define parse_xvfs_minirivet_getbyte(var) var = fgetc(fp); if (var == EOF) { break; }
0ffa676110 2019-12-02 348:
0ffa676110 2019-12-02 349: mode = XVFS_MINIRIVET_MODE_COPY;
9f07de5ec5 2019-12-02 350: tcl_buffer_p = NULL;
0ffa676110 2019-12-02 351: while (1) {
0ffa676110 2019-12-02 352: parse_xvfs_minirivet_getbyte(ch);
0ffa676110 2019-12-02 353:
0ffa676110 2019-12-02 354: switch (mode) {
0ffa676110 2019-12-02 355: case XVFS_MINIRIVET_MODE_COPY:
0ffa676110 2019-12-02 356: if (ch == '<') {
0ffa676110 2019-12-02 357: parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02 358: if (ch_buf != '?') {
0ffa676110 2019-12-02 359: fputc('<', outfp);
0ffa676110 2019-12-02 360: ch = ch_buf;
0ffa676110 2019-12-02 361:
0ffa676110 2019-12-02 362: break;
0ffa676110 2019-12-02 363: }
0ffa676110 2019-12-02 364:
0ffa676110 2019-12-02 365: tcl_buffer_p = tcl_buffer;
0ffa676110 2019-12-02 366: parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02 367: if (ch_buf == '=') {
0ffa676110 2019-12-02 368: mode = XVFS_MINIRIVET_MODE_TCL_PRINT;
0ffa676110 2019-12-02 369: } else {
0ffa676110 2019-12-02 370: mode = XVFS_MINIRIVET_MODE_TCL;
0ffa676110 2019-12-02 371: *tcl_buffer_p = ch_buf;
0ffa676110 2019-12-02 372: tcl_buffer_p++;
0ffa676110 2019-12-02 373: }
0ffa676110 2019-12-02 374: *tcl_buffer_p = '\0';
0ffa676110 2019-12-02 375: continue;
0ffa676110 2019-12-02 376: }
0ffa676110 2019-12-02 377: break;
0ffa676110 2019-12-02 378: case XVFS_MINIRIVET_MODE_TCL:
0ffa676110 2019-12-02 379: case XVFS_MINIRIVET_MODE_TCL_PRINT:
0ffa676110 2019-12-02 380: if (ch == '?') {
0ffa676110 2019-12-02 381: parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02 382: if (ch_buf != '>') {
0ffa676110 2019-12-02 383: *tcl_buffer_p = ch;
0ffa676110 2019-12-02 384: tcl_buffer_p++;
0ffa676110 2019-12-02 385:
0ffa676110 2019-12-02 386: ch = ch_buf;
0ffa676110 2019-12-02 387:
0ffa676110 2019-12-02 388: break;
0ffa676110 2019-12-02 389: }
0ffa676110 2019-12-02 390:
0ffa676110 2019-12-02 391: *tcl_buffer_p = '\0';
0ffa676110 2019-12-02 392:
0ffa676110 2019-12-02 393: if (mode == XVFS_MINIRIVET_MODE_TCL_PRINT) {
0ffa676110 2019-12-02 394: parse_xvfs_minirivet_handle_tcl_print(outfp, options, &xvfs_state, tcl_buffer);
0ffa676110 2019-12-02 395: }
0ffa676110 2019-12-02 396:
0ffa676110 2019-12-02 397: mode = XVFS_MINIRIVET_MODE_COPY;
0ffa676110 2019-12-02 398: continue;
0ffa676110 2019-12-02 399: }
0ffa676110 2019-12-02 400: break;
0ffa676110 2019-12-02 401: }
0ffa676110 2019-12-02 402:
0ffa676110 2019-12-02 403: switch (mode) {
0ffa676110 2019-12-02 404: case XVFS_MINIRIVET_MODE_COPY:
0ffa676110 2019-12-02 405: fputc(ch, outfp);
0ffa676110 2019-12-02 406: break;
0ffa676110 2019-12-02 407: case XVFS_MINIRIVET_MODE_TCL:
0ffa676110 2019-12-02 408: case XVFS_MINIRIVET_MODE_TCL_PRINT:
0ffa676110 2019-12-02 409: *tcl_buffer_p = ch;
0ffa676110 2019-12-02 410: tcl_buffer_p++;
0ffa676110 2019-12-02 411: break;
0ffa676110 2019-12-02 412: }
0ffa676110 2019-12-02 413: }
0ffa676110 2019-12-02 414:
0ffa676110 2019-12-02 415: #undef parse_xvfs_minirivet_getbyte
1d38520446 2019-12-02 416:
1d38520446 2019-12-02 417: fclose(fp);
0ffa676110 2019-12-02 418:
0ffa676110 2019-12-02 419: return(1);
0ffa676110 2019-12-02 420: }
0ffa676110 2019-12-02 421:
0ffa676110 2019-12-02 422: static int xvfs_create(FILE *outfp, const struct options * const options) {
0ffa676110 2019-12-02 423: return(parse_xvfs_minirivet(outfp, "lib/xvfs/xvfs.c.rvt", options));
0ffa676110 2019-12-02 424: }
0ffa676110 2019-12-02 425:
0ffa676110 2019-12-02 426: /*
0ffa676110 2019-12-02 427: * Parse command line options
0ffa676110 2019-12-02 428: */
20809b08ce 2019-12-01 429: static int parse_options(int argc, char **argv, struct options *options) {
20809b08ce 2019-12-01 430: char *arg;
20809b08ce 2019-12-01 431: char **option;
20809b08ce 2019-12-01 432: int idx;
20809b08ce 2019-12-01 433: int retval;
20809b08ce 2019-12-01 434:
20809b08ce 2019-12-01 435: for (idx = 0; idx < argc; idx++) {
20809b08ce 2019-12-01 436: arg = argv[idx];
20809b08ce 2019-12-01 437:
20809b08ce 2019-12-01 438: if (strcmp(arg, "--directory") == 0) {
20809b08ce 2019-12-01 439: option = &options->directory;
20809b08ce 2019-12-01 440: } else if (strcmp(arg, "--name") == 0) {
20809b08ce 2019-12-01 441: option = &options->name;
20809b08ce 2019-12-01 442: } else {
20809b08ce 2019-12-01 443: fprintf(stderr, "Invalid argument %s\n", arg);
20809b08ce 2019-12-01 444:
20809b08ce 2019-12-01 445: return(0);
20809b08ce 2019-12-01 446: }
20809b08ce 2019-12-01 447:
20809b08ce 2019-12-01 448: idx++;
20809b08ce 2019-12-01 449: arg = argv[idx];
20809b08ce 2019-12-01 450: *option = arg;
20809b08ce 2019-12-01 451: }
20809b08ce 2019-12-01 452:
20809b08ce 2019-12-01 453: retval = 1;
20809b08ce 2019-12-01 454: if (!options->directory) {
20809b08ce 2019-12-01 455: fprintf(stderr, "error: --directory must be specified\n");
20809b08ce 2019-12-01 456: retval = 0;
20809b08ce 2019-12-01 457: }
20809b08ce 2019-12-01 458:
20809b08ce 2019-12-01 459: if (!options->name) {
20809b08ce 2019-12-01 460: fprintf(stderr, "error: --name must be specified\n");
20809b08ce 2019-12-01 461: retval = 0;
20809b08ce 2019-12-01 462: }
20809b08ce 2019-12-01 463:
20809b08ce 2019-12-01 464: return(retval);
20809b08ce 2019-12-01 465: }
20809b08ce 2019-12-01 466:
20809b08ce 2019-12-01 467: int main(int argc, char **argv) {
20809b08ce 2019-12-01 468: struct options options = {0};
20809b08ce 2019-12-01 469: int parse_options_ret, xvfs_create_ret;
20809b08ce 2019-12-01 470:
20809b08ce 2019-12-01 471: argc--;
20809b08ce 2019-12-01 472: argv++;
20809b08ce 2019-12-01 473:
20809b08ce 2019-12-01 474: parse_options_ret = parse_options(argc, argv, &options);
20809b08ce 2019-12-01 475: if (!parse_options_ret) {
20809b08ce 2019-12-01 476: return(1);
20809b08ce 2019-12-01 477: }
20809b08ce 2019-12-01 478:
0ffa676110 2019-12-02 479: xvfs_create_ret = xvfs_create(stdout, &options);
20809b08ce 2019-12-01 480: if (!xvfs_create_ret) {
20809b08ce 2019-12-01 481: return(1);
20809b08ce 2019-12-01 482: }
20809b08ce 2019-12-01 483:
20809b08ce 2019-12-01 484: return(0);
20809b08ce 2019-12-01 485: }