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: }
0ffa676110 2019-12-02 267:
0ffa676110 2019-12-02 268: fprintf(outfp, "\tstatic const long * const pathIndex_hashTable[%i] = {\n", bucket_count);
0ffa676110 2019-12-02 269: for (idx1 = 0; idx1 < bucket_count; idx1++) {
0ffa676110 2019-12-02 270: fprintf(outfp, "\t\tpathIndex_hashTable_%i,\n", idx1);
0ffa676110 2019-12-02 271: }
0ffa676110 2019-12-02 272: fprintf(outfp, "\t};\n");
0ffa676110 2019-12-02 273: return;
0ffa676110 2019-12-02 274: }
0ffa676110 2019-12-02 275:
0ffa676110 2019-12-02 276: static void parse_xvfs_minirivet_hashtable_body(FILE *outfp, struct xvfs_state *xvfs_state) {
0ffa676110 2019-12-02 277: fprintf(outfp, "\tpathIndex_hash = Tcl_ZlibAdler32(0, (unsigned char *) path, pathLen) %% %i;\n", xvfs_state->bucket_count);
0ffa676110 2019-12-02 278: fprintf(outfp, "\tfor (pathIndex_idx = 0; pathIndex_idx < %i; pathIndex_idx++) {\n", xvfs_state->max_index);
0ffa676110 2019-12-02 279: fprintf(outfp, "\t\tpathIndex = pathIndex_hashTable[pathIndex_hash][pathIndex_idx];\n");
0ffa676110 2019-12-02 280: fprintf(outfp, "\t\tif (pathIndex == XVFS_NAME_LOOKUP_ERROR) {\n");
0ffa676110 2019-12-02 281: fprintf(outfp, "\t\t\tbreak;\n");
0ffa676110 2019-12-02 282: fprintf(outfp, "\t\t}\n");
0ffa676110 2019-12-02 283: fprintf(outfp, "\n");
0ffa676110 2019-12-02 284: fprintf(outfp, "\t\tif (strcmp(path, xvfs_example_data[pathIndex].name) == 0) {\n");
0ffa676110 2019-12-02 285: fprintf(outfp, "\t\t\treturn(pathIndex);\n");
0ffa676110 2019-12-02 286: fprintf(outfp, "\t\t}\n");
0ffa676110 2019-12-02 287: fprintf(outfp, "\t}\n");
0ffa676110 2019-12-02 288: return;
0ffa676110 2019-12-02 289: }
0ffa676110 2019-12-02 290:
0ffa676110 2019-12-02 291: 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 292: char *buffer_p, *buffer_e;
0ffa676110 2019-12-02 293:
0ffa676110 2019-12-02 294: buffer_p = command;
0ffa676110 2019-12-02 295: while (*buffer_p && isspace(*buffer_p)) {
0ffa676110 2019-12-02 296: buffer_p++;
0ffa676110 2019-12-02 297: }
0ffa676110 2019-12-02 298:
0ffa676110 2019-12-02 299: buffer_e = buffer_p + strlen(buffer_p) - 1;
0ffa676110 2019-12-02 300: while (buffer_e >= buffer_p && isspace(*buffer_e)) {
0ffa676110 2019-12-02 301: *buffer_e = '\0';
0ffa676110 2019-12-02 302: buffer_e--;
0ffa676110 2019-12-02 303: }
0ffa676110 2019-12-02 304:
0ffa676110 2019-12-02 305: if (strcmp(buffer_p, "$::xvfs::fsName") == 0) {
0ffa676110 2019-12-02 306: fprintf(outfp, "%s", options->name);
0ffa676110 2019-12-02 307: } else if (strcmp(buffer_p, "$::xvfs::fileInfoStruct") == 0) {
0ffa676110 2019-12-02 308: fprintf(outfp, "static const struct xvfs_file_data xvfs_");
0ffa676110 2019-12-02 309: fprintf(outfp, "%s", options->name);
0ffa676110 2019-12-02 310: fprintf(outfp, "_data[] = {\n");
0ffa676110 2019-12-02 311: parse_xvfs_minirivet_directory(outfp, xvfs_state, options->directory, "");
0ffa676110 2019-12-02 312: fprintf(outfp, "};\n");
0ffa676110 2019-12-02 313: } else if (strcmp(buffer_p, "[zlib adler32 $::xvfs::fsName 0]") == 0) {
0ffa676110 2019-12-02 314: fprintf(outfp, "%lu", adler32(0, (unsigned char *) options->name, strlen(options->name)));
0ffa676110 2019-12-02 315: } else if (strcmp(buffer_p, "$hashTableHeader") == 0) {
0ffa676110 2019-12-02 316: parse_xvfs_minirivet_hashtable_header(outfp, xvfs_state);
0ffa676110 2019-12-02 317: } else if (strcmp(buffer_p, "[dict get $hashTable body]") == 0) {
0ffa676110 2019-12-02 318: parse_xvfs_minirivet_hashtable_body(outfp, xvfs_state);
0ffa676110 2019-12-02 319: } else {
0ffa676110 2019-12-02 320: fprintf(outfp, "@INVALID@%s@INVALID@", buffer_p);
0ffa676110 2019-12-02 321: }
0ffa676110 2019-12-02 322:
0ffa676110 2019-12-02 323: return;
0ffa676110 2019-12-02 324: }
0ffa676110 2019-12-02 325:
0ffa676110 2019-12-02 326: static int parse_xvfs_minirivet(FILE *outfp, const char * const file, const struct options * const options) {
0ffa676110 2019-12-02 327: struct xvfs_state xvfs_state;
0ffa676110 2019-12-02 328: FILE *fp;
0ffa676110 2019-12-02 329: int ch, ch_buf;
0ffa676110 2019-12-02 330: char tcl_buffer[8192], *tcl_buffer_p;
0ffa676110 2019-12-02 331: enum xvfs_minirivet_mode mode;
0ffa676110 2019-12-02 332:
0ffa676110 2019-12-02 333: fp = fopen(file, "r");
0ffa676110 2019-12-02 334: if (!fp) {
0ffa676110 2019-12-02 335: return(0);
0ffa676110 2019-12-02 336: }
0ffa676110 2019-12-02 337:
0ffa676110 2019-12-02 338: xvfs_state.child_count = 0;
0ffa676110 2019-12-02 339: xvfs_state.child_len = 65536;
0ffa676110 2019-12-02 340: xvfs_state.children = malloc(sizeof(*xvfs_state.children) * xvfs_state.child_len);
0ffa676110 2019-12-02 341:
0ffa676110 2019-12-02 342: #define parse_xvfs_minirivet_getbyte(var) var = fgetc(fp); if (var == EOF) { break; }
0ffa676110 2019-12-02 343:
0ffa676110 2019-12-02 344: mode = XVFS_MINIRIVET_MODE_COPY;
0ffa676110 2019-12-02 345: while (1) {
0ffa676110 2019-12-02 346: parse_xvfs_minirivet_getbyte(ch);
0ffa676110 2019-12-02 347:
0ffa676110 2019-12-02 348: switch (mode) {
0ffa676110 2019-12-02 349: case XVFS_MINIRIVET_MODE_COPY:
0ffa676110 2019-12-02 350: if (ch == '<') {
0ffa676110 2019-12-02 351: parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02 352: if (ch_buf != '?') {
0ffa676110 2019-12-02 353: fputc('<', outfp);
0ffa676110 2019-12-02 354: ch = ch_buf;
0ffa676110 2019-12-02 355:
0ffa676110 2019-12-02 356: break;
0ffa676110 2019-12-02 357: }
0ffa676110 2019-12-02 358:
0ffa676110 2019-12-02 359: tcl_buffer_p = tcl_buffer;
0ffa676110 2019-12-02 360: parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02 361: if (ch_buf == '=') {
0ffa676110 2019-12-02 362: mode = XVFS_MINIRIVET_MODE_TCL_PRINT;
0ffa676110 2019-12-02 363: } else {
0ffa676110 2019-12-02 364: mode = XVFS_MINIRIVET_MODE_TCL;
0ffa676110 2019-12-02 365: *tcl_buffer_p = ch_buf;
0ffa676110 2019-12-02 366: tcl_buffer_p++;
0ffa676110 2019-12-02 367: }
0ffa676110 2019-12-02 368: *tcl_buffer_p = '\0';
0ffa676110 2019-12-02 369: continue;
0ffa676110 2019-12-02 370: }
0ffa676110 2019-12-02 371: break;
0ffa676110 2019-12-02 372: case XVFS_MINIRIVET_MODE_TCL:
0ffa676110 2019-12-02 373: case XVFS_MINIRIVET_MODE_TCL_PRINT:
0ffa676110 2019-12-02 374: if (ch == '?') {
0ffa676110 2019-12-02 375: parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02 376: if (ch_buf != '>') {
0ffa676110 2019-12-02 377: *tcl_buffer_p = ch;
0ffa676110 2019-12-02 378: tcl_buffer_p++;
0ffa676110 2019-12-02 379:
0ffa676110 2019-12-02 380: ch = ch_buf;
0ffa676110 2019-12-02 381:
0ffa676110 2019-12-02 382: break;
0ffa676110 2019-12-02 383: }
0ffa676110 2019-12-02 384:
0ffa676110 2019-12-02 385: *tcl_buffer_p = '\0';
0ffa676110 2019-12-02 386:
0ffa676110 2019-12-02 387: if (mode == XVFS_MINIRIVET_MODE_TCL_PRINT) {
0ffa676110 2019-12-02 388: parse_xvfs_minirivet_handle_tcl_print(outfp, options, &xvfs_state, tcl_buffer);
0ffa676110 2019-12-02 389: }
0ffa676110 2019-12-02 390:
0ffa676110 2019-12-02 391: mode = XVFS_MINIRIVET_MODE_COPY;
0ffa676110 2019-12-02 392: continue;
0ffa676110 2019-12-02 393: }
0ffa676110 2019-12-02 394: break;
0ffa676110 2019-12-02 395: }
0ffa676110 2019-12-02 396:
0ffa676110 2019-12-02 397: switch (mode) {
0ffa676110 2019-12-02 398: case XVFS_MINIRIVET_MODE_COPY:
0ffa676110 2019-12-02 399: fputc(ch, outfp);
0ffa676110 2019-12-02 400: break;
0ffa676110 2019-12-02 401: case XVFS_MINIRIVET_MODE_TCL:
0ffa676110 2019-12-02 402: case XVFS_MINIRIVET_MODE_TCL_PRINT:
0ffa676110 2019-12-02 403: *tcl_buffer_p = ch;
0ffa676110 2019-12-02 404: tcl_buffer_p++;
0ffa676110 2019-12-02 405: break;
0ffa676110 2019-12-02 406: }
0ffa676110 2019-12-02 407: }
0ffa676110 2019-12-02 408:
0ffa676110 2019-12-02 409: #undef parse_xvfs_minirivet_getbyte
0ffa676110 2019-12-02 410:
0ffa676110 2019-12-02 411: return(1);
0ffa676110 2019-12-02 412: }
0ffa676110 2019-12-02 413:
0ffa676110 2019-12-02 414: static int xvfs_create(FILE *outfp, const struct options * const options) {
0ffa676110 2019-12-02 415: return(parse_xvfs_minirivet(outfp, "lib/xvfs/xvfs.c.rvt", options));
0ffa676110 2019-12-02 416: }
0ffa676110 2019-12-02 417:
0ffa676110 2019-12-02 418: /*
0ffa676110 2019-12-02 419: * Parse command line options
0ffa676110 2019-12-02 420: */
20809b08ce 2019-12-01 421: static int parse_options(int argc, char **argv, struct options *options) {
20809b08ce 2019-12-01 422: char *arg;
20809b08ce 2019-12-01 423: char **option;
20809b08ce 2019-12-01 424: int idx;
20809b08ce 2019-12-01 425: int retval;
20809b08ce 2019-12-01 426:
20809b08ce 2019-12-01 427: for (idx = 0; idx < argc; idx++) {
20809b08ce 2019-12-01 428: arg = argv[idx];
20809b08ce 2019-12-01 429:
20809b08ce 2019-12-01 430: if (strcmp(arg, "--directory") == 0) {
20809b08ce 2019-12-01 431: option = &options->directory;
20809b08ce 2019-12-01 432: } else if (strcmp(arg, "--name") == 0) {
20809b08ce 2019-12-01 433: option = &options->name;
20809b08ce 2019-12-01 434: } else {
20809b08ce 2019-12-01 435: fprintf(stderr, "Invalid argument %s\n", arg);
20809b08ce 2019-12-01 436:
20809b08ce 2019-12-01 437: return(0);
20809b08ce 2019-12-01 438: }
20809b08ce 2019-12-01 439:
20809b08ce 2019-12-01 440: idx++;
20809b08ce 2019-12-01 441: arg = argv[idx];
20809b08ce 2019-12-01 442: *option = arg;
20809b08ce 2019-12-01 443: }
20809b08ce 2019-12-01 444:
20809b08ce 2019-12-01 445: retval = 1;
20809b08ce 2019-12-01 446: if (!options->directory) {
20809b08ce 2019-12-01 447: fprintf(stderr, "error: --directory must be specified\n");
20809b08ce 2019-12-01 448: retval = 0;
20809b08ce 2019-12-01 449: }
20809b08ce 2019-12-01 450:
20809b08ce 2019-12-01 451: if (!options->name) {
20809b08ce 2019-12-01 452: fprintf(stderr, "error: --name 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: return(retval);
20809b08ce 2019-12-01 457: }
20809b08ce 2019-12-01 458:
20809b08ce 2019-12-01 459: int main(int argc, char **argv) {
20809b08ce 2019-12-01 460: struct options options = {0};
20809b08ce 2019-12-01 461: int parse_options_ret, xvfs_create_ret;
20809b08ce 2019-12-01 462:
20809b08ce 2019-12-01 463: argc--;
20809b08ce 2019-12-01 464: argv++;
20809b08ce 2019-12-01 465:
20809b08ce 2019-12-01 466: parse_options_ret = parse_options(argc, argv, &options);
20809b08ce 2019-12-01 467: if (!parse_options_ret) {
20809b08ce 2019-12-01 468: return(1);
20809b08ce 2019-12-01 469: }
20809b08ce 2019-12-01 470:
0ffa676110 2019-12-02 471: xvfs_create_ret = xvfs_create(stdout, &options);
20809b08ce 2019-12-01 472: if (!xvfs_create_ret) {
20809b08ce 2019-12-01 473: return(1);
20809b08ce 2019-12-01 474: }
20809b08ce 2019-12-01 475:
20809b08ce 2019-12-01 476: return(0);
20809b08ce 2019-12-01 477: }