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++) {
0ffa676110 2019-12-02 243: check_hash = adler32(0, 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;
0ffa676110 2019-12-02 350: while (1) {
0ffa676110 2019-12-02 351: parse_xvfs_minirivet_getbyte(ch);
0ffa676110 2019-12-02 352:
0ffa676110 2019-12-02 353: switch (mode) {
0ffa676110 2019-12-02 354: case XVFS_MINIRIVET_MODE_COPY:
0ffa676110 2019-12-02 355: if (ch == '<') {
0ffa676110 2019-12-02 356: parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02 357: if (ch_buf != '?') {
0ffa676110 2019-12-02 358: fputc('<', outfp);
0ffa676110 2019-12-02 359: ch = ch_buf;
0ffa676110 2019-12-02 360:
0ffa676110 2019-12-02 361: break;
0ffa676110 2019-12-02 362: }
0ffa676110 2019-12-02 363:
0ffa676110 2019-12-02 364: tcl_buffer_p = tcl_buffer;
0ffa676110 2019-12-02 365: parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02 366: if (ch_buf == '=') {
0ffa676110 2019-12-02 367: mode = XVFS_MINIRIVET_MODE_TCL_PRINT;
0ffa676110 2019-12-02 368: } else {
0ffa676110 2019-12-02 369: mode = XVFS_MINIRIVET_MODE_TCL;
0ffa676110 2019-12-02 370: *tcl_buffer_p = ch_buf;
0ffa676110 2019-12-02 371: tcl_buffer_p++;
0ffa676110 2019-12-02 372: }
0ffa676110 2019-12-02 373: *tcl_buffer_p = '\0';
0ffa676110 2019-12-02 374: continue;
0ffa676110 2019-12-02 375: }
0ffa676110 2019-12-02 376: break;
0ffa676110 2019-12-02 377: case XVFS_MINIRIVET_MODE_TCL:
0ffa676110 2019-12-02 378: case XVFS_MINIRIVET_MODE_TCL_PRINT:
0ffa676110 2019-12-02 379: if (ch == '?') {
0ffa676110 2019-12-02 380: parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02 381: if (ch_buf != '>') {
0ffa676110 2019-12-02 382: *tcl_buffer_p = ch;
0ffa676110 2019-12-02 383: tcl_buffer_p++;
0ffa676110 2019-12-02 384:
0ffa676110 2019-12-02 385: ch = ch_buf;
0ffa676110 2019-12-02 386:
0ffa676110 2019-12-02 387: break;
0ffa676110 2019-12-02 388: }
0ffa676110 2019-12-02 389:
0ffa676110 2019-12-02 390: *tcl_buffer_p = '\0';
0ffa676110 2019-12-02 391:
0ffa676110 2019-12-02 392: if (mode == XVFS_MINIRIVET_MODE_TCL_PRINT) {
0ffa676110 2019-12-02 393: parse_xvfs_minirivet_handle_tcl_print(outfp, options, &xvfs_state, tcl_buffer);
0ffa676110 2019-12-02 394: }
0ffa676110 2019-12-02 395:
0ffa676110 2019-12-02 396: mode = XVFS_MINIRIVET_MODE_COPY;
0ffa676110 2019-12-02 397: continue;
0ffa676110 2019-12-02 398: }
0ffa676110 2019-12-02 399: break;
0ffa676110 2019-12-02 400: }
0ffa676110 2019-12-02 401:
0ffa676110 2019-12-02 402: switch (mode) {
0ffa676110 2019-12-02 403: case XVFS_MINIRIVET_MODE_COPY:
0ffa676110 2019-12-02 404: fputc(ch, outfp);
0ffa676110 2019-12-02 405: break;
0ffa676110 2019-12-02 406: case XVFS_MINIRIVET_MODE_TCL:
0ffa676110 2019-12-02 407: case XVFS_MINIRIVET_MODE_TCL_PRINT:
0ffa676110 2019-12-02 408: *tcl_buffer_p = ch;
0ffa676110 2019-12-02 409: tcl_buffer_p++;
0ffa676110 2019-12-02 410: break;
0ffa676110 2019-12-02 411: }
0ffa676110 2019-12-02 412: }
0ffa676110 2019-12-02 413:
0ffa676110 2019-12-02 414: #undef parse_xvfs_minirivet_getbyte
0ffa676110 2019-12-02 415:
0ffa676110 2019-12-02 416: return(1);
0ffa676110 2019-12-02 417: }
0ffa676110 2019-12-02 418:
0ffa676110 2019-12-02 419: static int xvfs_create(FILE *outfp, const struct options * const options) {
0ffa676110 2019-12-02 420: return(parse_xvfs_minirivet(outfp, "lib/xvfs/xvfs.c.rvt", options));
0ffa676110 2019-12-02 421: }
0ffa676110 2019-12-02 422:
0ffa676110 2019-12-02 423: /*
0ffa676110 2019-12-02 424: * Parse command line options
0ffa676110 2019-12-02 425: */
20809b08ce 2019-12-01 426: static int parse_options(int argc, char **argv, struct options *options) {
20809b08ce 2019-12-01 427: char *arg;
20809b08ce 2019-12-01 428: char **option;
20809b08ce 2019-12-01 429: int idx;
20809b08ce 2019-12-01 430: int retval;
20809b08ce 2019-12-01 431:
20809b08ce 2019-12-01 432: for (idx = 0; idx < argc; idx++) {
20809b08ce 2019-12-01 433: arg = argv[idx];
20809b08ce 2019-12-01 434:
20809b08ce 2019-12-01 435: if (strcmp(arg, "--directory") == 0) {
20809b08ce 2019-12-01 436: option = &options->directory;
20809b08ce 2019-12-01 437: } else if (strcmp(arg, "--name") == 0) {
20809b08ce 2019-12-01 438: option = &options->name;
20809b08ce 2019-12-01 439: } else {
20809b08ce 2019-12-01 440: fprintf(stderr, "Invalid argument %s\n", arg);
20809b08ce 2019-12-01 441:
20809b08ce 2019-12-01 442: return(0);
20809b08ce 2019-12-01 443: }
20809b08ce 2019-12-01 444:
20809b08ce 2019-12-01 445: idx++;
20809b08ce 2019-12-01 446: arg = argv[idx];
20809b08ce 2019-12-01 447: *option = arg;
20809b08ce 2019-12-01 448: }
20809b08ce 2019-12-01 449:
20809b08ce 2019-12-01 450: retval = 1;
20809b08ce 2019-12-01 451: if (!options->directory) {
20809b08ce 2019-12-01 452: fprintf(stderr, "error: --directory must be specified\n");
20809b08ce 2019-12-01 453: retval = 0;
20809b08ce 2019-12-01 454: }
20809b08ce 2019-12-01 455:
20809b08ce 2019-12-01 456: if (!options->name) {
20809b08ce 2019-12-01 457: fprintf(stderr, "error: --name must be specified\n");
20809b08ce 2019-12-01 458: retval = 0;
20809b08ce 2019-12-01 459: }
20809b08ce 2019-12-01 460:
20809b08ce 2019-12-01 461: return(retval);
20809b08ce 2019-12-01 462: }
20809b08ce 2019-12-01 463:
20809b08ce 2019-12-01 464: int main(int argc, char **argv) {
20809b08ce 2019-12-01 465: struct options options = {0};
20809b08ce 2019-12-01 466: int parse_options_ret, xvfs_create_ret;
20809b08ce 2019-12-01 467:
20809b08ce 2019-12-01 468: argc--;
20809b08ce 2019-12-01 469: argv++;
20809b08ce 2019-12-01 470:
20809b08ce 2019-12-01 471: parse_options_ret = parse_options(argc, argv, &options);
20809b08ce 2019-12-01 472: if (!parse_options_ret) {
20809b08ce 2019-12-01 473: return(1);
20809b08ce 2019-12-01 474: }
20809b08ce 2019-12-01 475:
0ffa676110 2019-12-02 476: xvfs_create_ret = xvfs_create(stdout, &options);
20809b08ce 2019-12-01 477: if (!xvfs_create_ret) {
20809b08ce 2019-12-01 478: return(1);
20809b08ce 2019-12-01 479: }
20809b08ce 2019-12-01 480:
20809b08ce 2019-12-01 481: return(0);
20809b08ce 2019-12-01 482: }