118 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			118 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #include <stdio.h>
 | ||
|  | #include <stdlib.h>
 | ||
|  | #include <string.h>
 | ||
|  | #include "mujs.h"
 | ||
|  | 
 | ||
|  | /* -------------------- */ | ||
|  | /* these helper functions are from the official repl example */ | ||
|  | 
 | ||
|  | static void jsB_print(js_State *J) { | ||
|  | 	int i = 1, top = js_gettop(J); | ||
|  | 	for (; i < top; ++i) { | ||
|  | 		const char *s = js_tostring(J, i); | ||
|  | 		if (i > 1) putchar(' '); | ||
|  | 		/* note: the official example uses `fputs`, but `puts` makes more sense */ | ||
|  | 		puts(s); | ||
|  | 	} | ||
|  | 	putchar('\n'); | ||
|  | 	js_pushundefined(J); | ||
|  | } | ||
|  | 
 | ||
|  | static void report(js_State *J, const char *msg) { fprintf(stderr, "REPORT MSG: %s\n", msg); } | ||
|  | 
 | ||
|  | /* -------------------- */ | ||
|  | /* base64 encoder */ | ||
|  | 
 | ||
|  | const char Base64_map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||
|  | 
 | ||
|  | static int Base64_encode(char *dst, const char *src, int len) { | ||
|  | 	unsigned char c1 = 0, c2 = 0, c3 = 0; | ||
|  | 	char *p = dst; | ||
|  | 	size_t i = 0; | ||
|  | 
 | ||
|  | 	for(; i < len;) { | ||
|  | 		c1 = src[i++]; | ||
|  | 		*p++ = Base64_map[(c1 >> 2)]; | ||
|  | 
 | ||
|  | 		c2 = src[i++]; | ||
|  | 		*p++ = Base64_map[((c1 & 3) << 4) | (c2 >> 4)]; | ||
|  | 
 | ||
|  | 		c3 = src[i++]; | ||
|  | 		*p++ = Base64_map[((c2 & 15) << 2) | (c3 >> 6)]; | ||
|  | 		*p++ = Base64_map[c3 & 0x3F]; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if(i < len) { | ||
|  | 		c1 = src[i++]; | ||
|  | 		*p++ = Base64_map[(c1 >> 2)]; | ||
|  | 		if(i == len) { | ||
|  | 			*p++ = Base64_map[(c1 & 3) << 4]; | ||
|  | 			*p++ = '='; | ||
|  | 		} else { | ||
|  | 			c2 = src[i++]; | ||
|  | 			*p++ = Base64_map[((c1 & 3) << 4) | (c2 >> 4)]; | ||
|  | 			*p++ = Base64_map[(c2 & 15) << 2]; | ||
|  | 		} | ||
|  | 		*p++ = '='; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	*p++ = '\0'; | ||
|  | 	return p - dst; | ||
|  | } | ||
|  | 
 | ||
|  | /* -------------------- */ | ||
|  | /* read file from filesystem */ | ||
|  | 
 | ||
|  | static char *read_file(const char *filename, size_t *sz) { | ||
|  |   FILE *f = fopen(filename, "rb"); | ||
|  |   if(!f) return NULL; | ||
|  |   long fsize; { fseek(f, 0, SEEK_END); fsize = ftell(f); fseek(f, 0, SEEK_SET); } | ||
|  |   char *buf = (char *)malloc(fsize * sizeof(char)); | ||
|  |   *sz = fread((void *) buf, 1, fsize, f); | ||
|  |   fclose(f); | ||
|  |   return buf; | ||
|  | } | ||
|  | 
 | ||
|  | /* -------------------- */ | ||
|  | 
 | ||
|  | int main(int argc, char **argv) { | ||
|  | 	/* initialize mujs */ | ||
|  | 	js_State *J = js_newstate(NULL, NULL, 0); | ||
|  | 	js_setreport(J, report); | ||
|  | 
 | ||
|  | 	/* create `console.log` */ | ||
|  | 	js_newcfunction(J, jsB_print, "print", 0); | ||
|  | 	js_setglobal(J, "print"); | ||
|  | 	js_dostring(J, "var console = { log: print };"); | ||
|  | 
 | ||
|  | 	/* create `global` variable */ | ||
|  | 	js_dostring(J, "var global = (function() { return this; })(null);"); | ||
|  | 
 | ||
|  | 	/* load scripts */ | ||
|  | 	js_dofile(J, "shim.min.js"); | ||
|  | 	js_dofile(J, "xlsx.full.min.js"); | ||
|  | 
 | ||
|  | 	/* read file */ | ||
|  | 	size_t dlen; char *dbuf = read_file(argv[1], &dlen); | ||
|  | 
 | ||
|  | 	/* base64 encode the file */ | ||
|  | 	int sz = ((dlen + 2) / 3) * 4 + 1; | ||
|  | 	char *b64 = malloc(sz+1); | ||
|  | 	sz = Base64_encode(b64, dbuf, dlen); | ||
|  | 
 | ||
|  | 	/* create `buf` global from the data */ | ||
|  | 	js_pushlstring(J, b64, sz); | ||
|  | 	js_setglobal(J, "buf"); | ||
|  | 
 | ||
|  | 	/* parse file */ | ||
|  | 	js_dostring(J, "var wb = XLSX.read(buf, {type: 'base64'});"); | ||
|  | 
 | ||
|  | 	/* print CSV from first worksheet */ | ||
|  | 	js_dostring(J, "var ws = wb.Sheets[wb.SheetNames[0]]"); | ||
|  | 	js_dostring(J, "console.log(XLSX.utils.sheet_to_csv(ws));"); | ||
|  | 
 | ||
|  | 	/* cleanup */ | ||
|  | 	free(b64); | ||
|  | 	js_freestate(J); | ||
|  | 	return 0; | ||
|  | } |