Annotation For xvfs-create-c.c

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

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: 
2d9592486f 2019-12-02  331: static int parse_xvfs_minirivet(FILE *outfp, const char * const template, const struct options * const options) {
0ffa676110 2019-12-02  332: 	struct xvfs_state xvfs_state;
0ffa676110 2019-12-02  333: 	int ch, ch_buf;
2d9592486f 2019-12-02  334: 	int template_idx = 0;
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: 	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: 
2d9592486f 2019-12-02  342: #define parse_xvfs_minirivet_getbyte(var) var = template[template_idx]; template_idx++; if (var == 0) { break; }
0ffa676110 2019-12-02  343: 
0ffa676110 2019-12-02  344: 	mode = XVFS_MINIRIVET_MODE_COPY;
9f07de5ec5 2019-12-02  345: 	tcl_buffer_p = NULL;
0ffa676110 2019-12-02  346: 	while (1) {
0ffa676110 2019-12-02  347: 		parse_xvfs_minirivet_getbyte(ch);
0ffa676110 2019-12-02  348: 
0ffa676110 2019-12-02  349: 		switch (mode) {
0ffa676110 2019-12-02  350: 			case XVFS_MINIRIVET_MODE_COPY:
0ffa676110 2019-12-02  351: 				if (ch == '<') {
0ffa676110 2019-12-02  352: 					parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02  353: 					if (ch_buf != '?') {
0ffa676110 2019-12-02  354: 						fputc('<', outfp);
0ffa676110 2019-12-02  355: 						ch = ch_buf;
0ffa676110 2019-12-02  356: 
0ffa676110 2019-12-02  357: 						break;
0ffa676110 2019-12-02  358: 					}
0ffa676110 2019-12-02  359: 
0ffa676110 2019-12-02  360: 					tcl_buffer_p = tcl_buffer;
0ffa676110 2019-12-02  361: 					parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02  362: 					if (ch_buf == '=') {
0ffa676110 2019-12-02  363: 						mode = XVFS_MINIRIVET_MODE_TCL_PRINT;
0ffa676110 2019-12-02  364: 					} else {
0ffa676110 2019-12-02  365: 						mode = XVFS_MINIRIVET_MODE_TCL;
0ffa676110 2019-12-02  366: 						*tcl_buffer_p = ch_buf;
0ffa676110 2019-12-02  367: 						tcl_buffer_p++;
0ffa676110 2019-12-02  368: 					}
0ffa676110 2019-12-02  369: 					*tcl_buffer_p = '\0';
0ffa676110 2019-12-02  370: 					continue;
0ffa676110 2019-12-02  371: 				}
0ffa676110 2019-12-02  372: 				break;
0ffa676110 2019-12-02  373: 			case XVFS_MINIRIVET_MODE_TCL:
0ffa676110 2019-12-02  374: 			case XVFS_MINIRIVET_MODE_TCL_PRINT:
0ffa676110 2019-12-02  375: 				if (ch == '?') {
0ffa676110 2019-12-02  376: 					parse_xvfs_minirivet_getbyte(ch_buf);
0ffa676110 2019-12-02  377: 					if (ch_buf != '>') {
0ffa676110 2019-12-02  378: 						*tcl_buffer_p = ch;
0ffa676110 2019-12-02  379: 						tcl_buffer_p++;
0ffa676110 2019-12-02  380: 
0ffa676110 2019-12-02  381: 						ch = ch_buf;
0ffa676110 2019-12-02  382: 						
0ffa676110 2019-12-02  383: 						break;
0ffa676110 2019-12-02  384: 					}
0ffa676110 2019-12-02  385: 
0ffa676110 2019-12-02  386: 					*tcl_buffer_p = '\0';
0ffa676110 2019-12-02  387: 
0ffa676110 2019-12-02  388: 					if (mode == XVFS_MINIRIVET_MODE_TCL_PRINT) {
0ffa676110 2019-12-02  389: 						parse_xvfs_minirivet_handle_tcl_print(outfp, options, &xvfs_state, tcl_buffer);
0ffa676110 2019-12-02  390: 					}
0ffa676110 2019-12-02  391: 
0ffa676110 2019-12-02  392: 					mode = XVFS_MINIRIVET_MODE_COPY;
0ffa676110 2019-12-02  393: 					continue;
0ffa676110 2019-12-02  394: 				}
0ffa676110 2019-12-02  395: 				break;
0ffa676110 2019-12-02  396: 		}
0ffa676110 2019-12-02  397: 
0ffa676110 2019-12-02  398: 		switch (mode) {
0ffa676110 2019-12-02  399: 			case XVFS_MINIRIVET_MODE_COPY:
0ffa676110 2019-12-02  400: 				fputc(ch, outfp);
0ffa676110 2019-12-02  401: 				break;
0ffa676110 2019-12-02  402: 			case XVFS_MINIRIVET_MODE_TCL:
0ffa676110 2019-12-02  403: 			case XVFS_MINIRIVET_MODE_TCL_PRINT:
0ffa676110 2019-12-02  404: 				*tcl_buffer_p = ch;
0ffa676110 2019-12-02  405: 				tcl_buffer_p++;
0ffa676110 2019-12-02  406: 				break;
0ffa676110 2019-12-02  407: 		}
0ffa676110 2019-12-02  408: 	}
0ffa676110 2019-12-02  409: 
0ffa676110 2019-12-02  410: #undef parse_xvfs_minirivet_getbyte
0ffa676110 2019-12-02  411: 
0ffa676110 2019-12-02  412: 	return(1);
0ffa676110 2019-12-02  413: }
0ffa676110 2019-12-02  414: 
0ffa676110 2019-12-02  415: static int xvfs_create(FILE *outfp, const struct options * const options) {
2d9592486f 2019-12-02  416: 	const int template_len = 65536;
2d9592486f 2019-12-02  417: 	const char * const template_file = "lib/xvfs/xvfs.c.rvt";
2d9592486f 2019-12-02  418: 	FILE *fp;
2d9592486f 2019-12-02  419: 	char *template, *template_p;
2d9592486f 2019-12-02  420: 	int template_remain;
2d9592486f 2019-12-02  421: 	size_t fread_ret;
2d9592486f 2019-12-02  422: 	int retval;
2d9592486f 2019-12-02  423: 
2d9592486f 2019-12-02  424: 	fp = fopen(template_file, "r");
2d9592486f 2019-12-02  425: 	if (!fp) {
2d9592486f 2019-12-02  426: 		return(0);
2d9592486f 2019-12-02  427: 	}
2d9592486f 2019-12-02  428: 
2d9592486f 2019-12-02  429: 	template = malloc(template_len);
2d9592486f 2019-12-02  430: 	template_remain = template_len;
2d9592486f 2019-12-02  431: 	if (!template) {
2d9592486f 2019-12-02  432: 		fclose(fp);
2d9592486f 2019-12-02  433: 
2d9592486f 2019-12-02  434: 		return(0);
2d9592486f 2019-12-02  435: 	}
2d9592486f 2019-12-02  436: 
2d9592486f 2019-12-02  437: 	template_p = template;
2d9592486f 2019-12-02  438: 	while (1) {
2d9592486f 2019-12-02  439: 		fread_ret = fread(template_p, 1, template_remain, fp);
2d9592486f 2019-12-02  440: 		if (fread_ret <= 0) {
2d9592486f 2019-12-02  441: 			break;
2d9592486f 2019-12-02  442: 		}
2d9592486f 2019-12-02  443: 
2d9592486f 2019-12-02  444: 		template_p += fread_ret;
2d9592486f 2019-12-02  445: 		template_remain -= fread_ret;
2d9592486f 2019-12-02  446: 	}
2d9592486f 2019-12-02  447: 	if (template_remain > 0) {
2d9592486f 2019-12-02  448: 		*template_p = '\0';
2d9592486f 2019-12-02  449: 	}
2d9592486f 2019-12-02  450: 
2d9592486f 2019-12-02  451: 	fclose(fp);
2d9592486f 2019-12-02  452: 
2d9592486f 2019-12-02  453: 	retval = parse_xvfs_minirivet(outfp, template, options);
2d9592486f 2019-12-02  454: 
2d9592486f 2019-12-02  455: 	free(template);
2d9592486f 2019-12-02  456: 
2d9592486f 2019-12-02  457: 	return(retval);
0ffa676110 2019-12-02  458: }
0ffa676110 2019-12-02  459: 
0ffa676110 2019-12-02  460: /*
0ffa676110 2019-12-02  461:  * Parse command line options
0ffa676110 2019-12-02  462:  */
20809b08ce 2019-12-01  463: static int parse_options(int argc, char **argv, struct options *options) {
20809b08ce 2019-12-01  464: 	char *arg;
20809b08ce 2019-12-01  465: 	char **option;
20809b08ce 2019-12-01  466: 	int idx;
20809b08ce 2019-12-01  467: 	int retval;
20809b08ce 2019-12-01  468: 
20809b08ce 2019-12-01  469: 	for (idx = 0; idx < argc; idx++) {
20809b08ce 2019-12-01  470: 		arg = argv[idx];
20809b08ce 2019-12-01  471: 
20809b08ce 2019-12-01  472: 		if (strcmp(arg, "--directory") == 0) {
20809b08ce 2019-12-01  473: 			option = &options->directory;
20809b08ce 2019-12-01  474: 		} else if (strcmp(arg, "--name") == 0) {
20809b08ce 2019-12-01  475: 			option = &options->name;
20809b08ce 2019-12-01  476: 		} else {
20809b08ce 2019-12-01  477: 			fprintf(stderr, "Invalid argument %s\n", arg);
20809b08ce 2019-12-01  478: 
20809b08ce 2019-12-01  479: 			return(0);
20809b08ce 2019-12-01  480: 		}
20809b08ce 2019-12-01  481: 
20809b08ce 2019-12-01  482: 		idx++;
20809b08ce 2019-12-01  483: 		arg = argv[idx];
20809b08ce 2019-12-01  484: 		*option = arg;
20809b08ce 2019-12-01  485: 	}
20809b08ce 2019-12-01  486: 
20809b08ce 2019-12-01  487: 	retval = 1;
20809b08ce 2019-12-01  488: 	if (!options->directory) {		
20809b08ce 2019-12-01  489: 		fprintf(stderr, "error: --directory must be specified\n");
20809b08ce 2019-12-01  490: 		retval = 0;
20809b08ce 2019-12-01  491: 	}
20809b08ce 2019-12-01  492: 
20809b08ce 2019-12-01  493: 	if (!options->name) {
20809b08ce 2019-12-01  494: 		fprintf(stderr, "error: --name must be specified\n");
20809b08ce 2019-12-01  495: 		retval = 0;
20809b08ce 2019-12-01  496: 	}
20809b08ce 2019-12-01  497: 
20809b08ce 2019-12-01  498: 	return(retval);
20809b08ce 2019-12-01  499: }
20809b08ce 2019-12-01  500: 
20809b08ce 2019-12-01  501: int main(int argc, char **argv) {
20809b08ce 2019-12-01  502: 	struct options options = {0};
20809b08ce 2019-12-01  503: 	int parse_options_ret, xvfs_create_ret;
20809b08ce 2019-12-01  504: 
20809b08ce 2019-12-01  505: 	argc--;
20809b08ce 2019-12-01  506: 	argv++;
20809b08ce 2019-12-01  507: 
20809b08ce 2019-12-01  508: 	parse_options_ret = parse_options(argc, argv, &options);
20809b08ce 2019-12-01  509: 	if (!parse_options_ret) {
20809b08ce 2019-12-01  510: 		return(1);
20809b08ce 2019-12-01  511: 	}
20809b08ce 2019-12-01  512: 
0ffa676110 2019-12-02  513: 	xvfs_create_ret = xvfs_create(stdout, &options);
20809b08ce 2019-12-01  514: 	if (!xvfs_create_ret) {
20809b08ce 2019-12-01  515: 		return(1);
20809b08ce 2019-12-01  516: 	}
20809b08ce 2019-12-01  517: 
20809b08ce 2019-12-01  518: 	return(0);
20809b08ce 2019-12-01  519: }