Annotation For xvfs-create-c.c

Origin for each line in xvfs-create-c.c from check-in eebfe1f40f:

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