void luaO_chunkid (char *out, const char *source, size_t bufflen) { if (*source == '=') { c_strncpy(out, source+1, bufflen); /* remove first char */ out[bufflen-1] = '\0'; /* ensures null termination */ } else { /* out = "source", or "...source" */ if (*source == '@') { size_t l; source++; /* skip the `@' */ bufflen -= sizeof(" '...' "); l = c_strlen(source); c_strcpy(out, ""); if (l > bufflen) { source += (l-bufflen); /* get last part of file name */ c_strcat(out, "..."); } c_strcat(out, source); } else { /* out = [string "string"] */ size_t len = c_strcspn(source, "\n\r"); /* stop at first newline */ bufflen -= sizeof(" [string \"...\"] "); if (len > bufflen) len = bufflen; c_strcpy(out, "[string \""); if (source[len] != '\0') { /* must truncate? */ c_strncat(out, source, len); c_strcat(out, "..."); } else c_strcat(out, source); c_strcat(out, "\"]"); } } }
void fxSerializeJSON(txMachine* the, txJSONSerializer* theSerializer) { txSlot* aSlot; txInteger aFlag; aSlot = fxGetInstance(the, mxThis); theSerializer->offset = 0; theSerializer->size = 1024; theSerializer->buffer = c_malloc(1024); if (!theSerializer->buffer) mxUnknownError("out of memory"); if (mxArgc > 1) { aSlot = mxArgv(1); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsFunction(aSlot)) theSerializer->replacer = mxArgv(1); else if (mxIsArray(aSlot)) mxSyntaxError("not yet implememented"); } } if (mxArgc > 2) { aSlot = mxArgv(2); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsNumber(aSlot) || mxIsString(aSlot)) aSlot = aSlot->next; } if ((aSlot->kind == XS_INTEGER_KIND) || (aSlot->kind == XS_NUMBER_KIND)) { txInteger aCount = fxToInteger(the, aSlot), anIndex; if (aCount < 0) aCount = 0; else if (aCount > 10) aCount = 10; for (anIndex = 0; anIndex < aCount; anIndex++) theSerializer->indent[anIndex] = ' '; } else if (mxIsStringPrimitive(aSlot)) c_strncpy((char *)theSerializer->indent, aSlot->value.string, 10); } theSerializer->stack = the->stack; mxPush(mxObjectPrototype); fxNewObjectInstance(the); aFlag = 0; if (mxArgc > 0) mxPushSlot(mxArgv(0)); else mxPushUndefined(); mxPush(mxEmptyString); fxSerializeJSONProperty(the, theSerializer, &aFlag); the->stack++; }
static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { const char *p = strfrmt; while (*p != '\0' && c_strchr(FLAGS, *p) != NULL) p++; /* skip flags */ if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) luaL_error(L, "invalid format (repeated flags)"); if (isdigit(uchar(*p))) p++; /* skip width */ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ if (*p == '.') { p++; if (isdigit(uchar(*p))) p++; /* skip precision */ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ } if (isdigit(uchar(*p))) luaL_error(L, "invalid format (width or precision too long)"); *(form++) = '%'; c_strncpy(form, strfrmt, p - strfrmt + 1); form += p - strfrmt + 1; *form = '\0'; return p; }
void fx_JSON_stringify(txMachine* the) { txSlot* aSlot; volatile txJSONSerializer aSerializer; txFlag aFlag; mxTry(the) { aSlot = fxGetInstance(the, mxThis); if (aSlot->flag & XS_SANDBOX_FLAG) the->frame->flag |= XS_SANDBOX_FLAG; else the->frame->flag |= the->frame->next->flag & XS_SANDBOX_FLAG; c_memset((txJSONSerializer*)&aSerializer, 0, sizeof(aSerializer)); aSerializer.offset = 0; aSerializer.size = 1024; aSerializer.buffer = c_malloc(1024); if (!aSerializer.buffer) fxThrowError(the, XS_RANGE_ERROR); if (mxArgc > 1) { aSlot = mxArgv(1); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsFunction(aSlot)) aSerializer.replacer = mxArgv(1); else if (mxIsArray(aSlot)) mxDebug0(the, XS_SYNTAX_ERROR, "not yet implememented"); } } if (mxArgc > 2) { aSlot = mxArgv(2); if (mxIsReference(aSlot)) { aSlot = fxGetInstance(the, aSlot); if (mxIsNumber(aSlot) || mxIsString(aSlot)) aSlot = aSlot->next; } if ((aSlot->kind == XS_INTEGER_KIND) || (aSlot->kind == XS_NUMBER_KIND)) { txInteger aCount = fxToInteger(the, aSlot), anIndex; if (aCount < 0) aCount = 0; else if (aCount > 10) aCount = 10; for (anIndex = 0; anIndex < aCount; anIndex++) aSerializer.indent[anIndex] = ' '; } else if (aSlot->kind == XS_STRING_KIND) c_strncpy((char *)aSerializer.indent, aSlot->value.string, 10); } aSerializer.stack = the->stack; *(--the->stack) = mxObjectPrototype; fxNewObjectInstance(the); aFlag = 0; if (mxArgc > 0) *(--the->stack) = *mxArgv(0); else mxZeroSlot(--the->stack); *(--the->stack) = mxEmptyString; fxSerializeJSONProperty(the, (txJSONSerializer*)&aSerializer, &aFlag); the->stack++; if (aSerializer.offset) { mxResult->value.string = (txString)fxNewChunk(the, aSerializer.offset + 1); c_memcpy(mxResult->value.string, aSerializer.buffer, aSerializer.offset); mxResult->value.string[aSerializer.offset] = 0; mxResult->kind = XS_STRING_KIND; } c_free(aSerializer.buffer); } mxCatch(the) { if (aSerializer.buffer) c_free(aSerializer.buffer); fxJump(the); } }
int main(int argc, char* argv[]) { int argi; txString base = NULL; txString output = NULL; txString input = NULL; char name[PATH_MAX]; char path[PATH_MAX]; txLinker _linker; txLinker* linker = &_linker; txInteger modulo = 0; txLinkerScript** link; txLinkerScript* script; FILE* file = C_NULL; txSize size; txByte byte; fxInitializeLinker(linker); if (c_setjmp(linker->jmp_buf) == 0) { c_strcpy(name, "a"); link = &(linker->firstScript); for (argi = 1; argi < argc; argi++) { if (!c_strcmp(argv[argi], "-a")) { argi++; c_strncpy(name, argv[argi], sizeof(name)); } else if (!c_strcmp(argv[argi], "-b")) { argi++; if (argi >= argc) fxReportError(linker, "-b: no directory"); base = fxRealDirectoryPath(linker, argv[argi]); if (!base) fxReportError(linker, "-b '%s': directory not found", argv[argi]); } else if (!c_strcmp(argv[argi], "-o")) { argi++; if (argi >= argc) fxReportError(linker, "-o: no directory"); output = fxRealDirectoryPath(linker, argv[argi]); if (!output) fxReportError(linker, "-o '%s': directory not found", argv[argi]); } else if (!c_strcmp(argv[argi], "-r")) { argi++; if (argi >= argc) fxReportError(linker, "-r: no modulo"); modulo = (txInteger)fxStringToNumber(linker->dtoa, argv[argi], 1); if (modulo <= 0) fxReportError(linker, "-r: invalid modulo"); linker->symbolModulo = modulo; } else { input = fxRealFilePath(linker, argv[argi]); if (!input) fxReportError(linker, "'%s': file not found", argv[argi]); fxLoadScript(linker, input, link, &file); link = &((*link)->nextScript); } } if (!output) output = fxRealDirectoryPath(linker, "."); if (!base) base = output; linker->symbolTable = fxNewLinkerChunkClear(linker, linker->symbolModulo * sizeof(txSymbol*)); c_strcpy(path, output); c_strcat(path, name); c_strcat(path, ".xsa"); if (!modulo && fxRealFilePath(linker, path)) fxLoadArchive(linker, path, &file); size = c_strlen(base); script = linker->firstScript; while (script) { fxBaseScript(linker, script, base, size); script = script->nextScript; } fxBufferPaths(linker); fxDefaultSymbols(linker); script = linker->firstScript; while (script) { fxMapScript(linker, script); script = script->nextScript; } fxBufferSymbols(linker, modulo); file = fopen(path, "wb"); mxThrowElse(file); size = 8 + 8 + 4 + 8 + linker->symbolsSize + 8 + linker->pathsSize + (8 * linker->scriptCount) + linker->codeSize; size = htonl(size); mxThrowElse(fwrite(&size, 4, 1, file) == 1); mxThrowElse(fwrite("XS6A", 4, 1, file) == 1); size = 8 + 4; size = htonl(size); mxThrowElse(fwrite(&size, 4, 1, file) == 1); mxThrowElse(fwrite("VERS", 4, 1, file) == 1); byte = XS_MAJOR_VERSION; mxThrowElse(fwrite(&byte, 1, 1, file) == 1); byte = XS_MINOR_VERSION; mxThrowElse(fwrite(&byte, 1, 1, file) == 1); byte = XS_PATCH_VERSION; mxThrowElse(fwrite(&byte, 1, 1, file) == 1); byte = (linker->hostsCount) ? 1 : 0; mxThrowElse(fwrite(&byte, 1, 1, file) == 1); size = 8 + linker->symbolsSize; size = htonl(size); mxThrowElse(fwrite(&size, 4, 1, file) == 1); mxThrowElse(fwrite("SYMB", 4, 1, file) == 1); mxThrowElse(fwrite(linker->symbolsBuffer, linker->symbolsSize, 1, file) == 1); size = 8 + linker->pathsSize; size = htonl(size); mxThrowElse(fwrite(&size, 4, 1, file) == 1); mxThrowElse(fwrite("PATH", 4, 1, file) == 1); mxThrowElse(fwrite(linker->pathsBuffer, linker->pathsSize, 1, file) == 1); script = linker->firstScript; while (script) { size = 8 + script->codeSize; size = htonl(size); mxThrowElse(fwrite(&size, 4, 1, file) == 1); mxThrowElse(fwrite("CODE", 4, 1, file) == 1); mxThrowElse(fwrite(script->codeBuffer, script->codeSize, 1, file) == 1); script = script->nextScript; } fclose(file); file = NULL; if (linker->hostsCount || modulo) { c_strcpy(path, base); c_strcat(path, name); c_strcat(path, ".xs.h"); file = fopen(path, "w"); mxThrowElse(file); fprintf(file, "/* XS GENERATED FILE; DO NOT EDIT! */\n\n"); fprintf(file, "#include <xs.h>\n\n"); fxWriteExterns(linker, file); fxWriteIDs(linker, file); fclose(file); file = NULL; c_strcpy(path, base); c_strcat(path, name); c_strcat(path, ".xs.c"); file = fopen(path, "w"); mxThrowElse(file); fprintf(file, "/* XS GENERATED FILE; DO NOT EDIT! */\n\n"); if (modulo) fprintf(file, "#include <xs6All.h>\n\n"); fprintf(file, "#include \"%s.xs.h\"\n\n", name); if (modulo) { txS2 c, i; txSymbol** address; c = (txS2)(linker->symbolIndex); address = &(linker->symbolArray[0]); for (i = 0; i < c; i++) { txSymbol* symbol = *address; fprintf(file, "static const txSlot xs_key_%d = {\n", symbol->ID & 0x7FFF); if (symbol->next) fprintf(file, "\t(txSlot *)&xs_key_%d,\n", symbol->next->ID & 0x7FFF); else fprintf(file, "\tNULL,\n"); if (i < XS_SYMBOL_ID_COUNT) { fprintf(file, "\tXS_NO_ID, XS_DONT_ENUM_FLAG | XS_MARK_FLAG, XS_STRING_X_KIND,\n"); fprintf(file, "\t{ .string = \""); fxWriteSymbolString(linker, file, symbol->string); fprintf(file, "\" }\n"); } else { fprintf(file, "\t%d, XS_DONT_ENUM_FLAG | XS_MARK_FLAG, XS_KEY_X_KIND,\n", (int)symbol->ID); fprintf(file, "\t{ .key = {\""); fxWriteSymbolString(linker, file, symbol->string); fprintf(file, "\", 0x%X} }\n", (int)symbol->sum); } fprintf(file, "};\n"); address++; } fprintf(file, "static const txSlot *xs_keys[%d] = {\n", c); address = &(linker->symbolArray[0]); for (i = 0; i < c; i++) { txSymbol* symbol = *address; fprintf(file, "\t&xs_key_%d,\n", symbol->ID & 0x7FFF); address++; } fprintf(file, "};\n\n"); fprintf(file, "static void xsHostKeys(txMachine* the)\n"); fprintf(file, "{\n"); fprintf(file, "\ttxSlot* code = &mxIDs;\n"); fprintf(file, "\ttxInteger i;\n"); fprintf(file, "\tmxCheck(the, the->nameModulo == %ld);\n", modulo); fprintf(file, "\tcode->value.code = (txByte *)fxNewChunk(the, %d * sizeof(txID));\n", c); fprintf(file, "\tcode->kind = XS_CODE_KIND;\n"); fprintf(file, "\tfor (i = 0; i < XS_SYMBOL_ID_COUNT; i++) {\n"); fprintf(file, "\t\ttxSlot *description = (txSlot *)xs_keys[i];\n"); fprintf(file, "\t\tthe->keyArray[i] = description;\n"); fprintf(file, "\t\tmxID(i) = 0x8000 | i;\n"); fprintf(file, "\t}\n"); fprintf(file, "\tfor (; i < %d; i++) {\n", c); fprintf(file, "\t\ttxSlot *key = (txSlot *)xs_keys[i];\n"); fprintf(file, "\t\tthe->keyArray[i] = key;\n"); fprintf(file, "\t\tthe->nameTable[key->value.key.sum %% %ld] = key;\n", modulo); fprintf(file, "\t\tmxID(i) = key->ID;\n"); fprintf(file, "\t}\n"); fprintf(file, "\tthe->keyIndex = %d;\n", c); fprintf(file, "\tthe->keyOffset = %d;\n", c); fprintf(file, "}\n\n"); } fxWriteHosts(linker, file, modulo); fclose(file); file = NULL; } } else { if (linker->error != C_EINVAL) { #if mxWindows char buffer[2048]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, linker->error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL); fprintf(stderr, "### %s\n", buffer); #else fprintf(stderr, "### %s\n", strerror(linker->error)); #endif } } if (file) fclose(file); fxTerminateLinker(linker); return linker->error; }