ekSyntax * ekSyntaxCreate(struct ekContext * E, ekU32 type, ekS32 line) { ekSyntax * syntax = (ekSyntax *)ekAlloc(sizeof(ekSyntax)); syntax->type = type; syntax->line = line; return syntax; }
ekValueType *ekValueTypeCreate(struct ekContext *E, const char *name, int format) { ekValueType *type = ekAlloc(sizeof(ekValueType)); strcpy(type->name, name); type->format = format; return type; }
ekError *ekErrorCreate(struct ekContext *E, const char *filename, ekS32 lineNo, const char *source, const char *loc, const char *explanation) { ekError *error = (ekError *)ekAlloc(sizeof(ekError)); ekStringSet(E, &error->filename, filename); error->lineNo = lineNo; ekStringSet(E, &error->explanation, explanation); if(loc) { // Find the full line where things went wrong, and store the location in it const char *line = loc; const char *end; while((line != source) && (*line != '\n') && (*line != '\r')) { --line; } if((*line == '\n') || (*line == '\r')) { ++line; } end = line; while(*end && (*end != '\n') && (*end != '\r')) { ++end; } ekStringSetLen(E, &error->line, line, end - line); error->col = loc - line; } return error; }
static ekU32 fileRead(struct ekContext *E, ekU32 argCount) { ekValue *thisValue; ekValue *ret = ekValueNullPtr; ekValue *bytesValue = NULL; int bytes = 0; ekFile *file; if(!ekContextGetArgs(E, argCount, "*F|i", &thisValue, &bytesValue)) { return ekContextArgsFailure(E, argCount, "file.read([optional int] bytes)"); } file = (ekFile *)thisValue->ptrVal; switchState(E, file, EFS_READ); if(file->handle) { if(bytesValue) { bytesValue = ekValueToInt(E, bytesValue); bytes = bytesValue->intVal; ekValueRemoveRefNote(E, bytesValue, "bytesValue temporary no longer needed"); } else { // we want "the rest" of the file (could be the whole thing if you just opened it) int end; int currentPos = ftell(file->handle); fseek(file->handle, 0, SEEK_END); end = ftell(file->handle); fseek(file->handle, currentPos, SEEK_SET); bytes = end - currentPos; } if(bytes > 0) { char *data = ekAlloc(bytes+1); int bytesRead = fread(data, 1, bytes, file->handle); if(bytesRead >= 0) { data[bytesRead] = 0; ret = ekValueDonateString(E, data); } else { ekFree(data); } } } ekValueRemoveRefNote(E, thisValue, "fileRead no longer needs thisValue"); ekContextReturn(E, ret); // will be the data if we succesfully read }
ekChunk * ekChunkCreate(struct ekContext * E, const char * sourcePath, ekBool useSourcePathForImports) { ekChunk * chunk = (ekChunk *)ekAlloc(sizeof(ekChunk)); if (sourcePath) { ekContextAbsolutePath(E, sourcePath, &chunk->sourcePath, ekFalse); if (useSourcePathForImports) { ekContextAbsolutePath(E, sourcePath, &chunk->searchPath, ekTrue); } } return chunk; }
static void addPermanentFile(struct ekContext *E, ekValue *module, const char *name, FILE *f, int permanentState) { ekValue *fileValue = ekValueCreate(E, ekValueTypeId(E, 'F')); ekFile *file = (ekFile *)ekAlloc(sizeof(ekFile)); file->filename = ekValueCreateString(E, name); file->state = permanentState; file->permanent = ekTrue; file->handle = f; fileValue->ptrVal = file; ekValueObjectSetMember(E, module, name, fileValue); }
static ekU32 newFile(struct ekContext *E, ekU32 argCount) { ekValue *ret = ekValueNullPtr; ekValue *filenameValue = NULL; ekFile *file; if(!ekContextGetArgs(E, argCount, "s", &filenameValue)) { return ekContextArgsFailure(E, argCount, "file([string] filename)"); } ret = ekValueCreate(E, ekValueTypeId(E, 'F')); file = (ekFile *)ekAlloc(sizeof(ekFile)); file->filename = absolutePath(E, filenameValue); // takes ownership ret->ptrVal = file; ekContextReturn(E, ret); }
static ekU32 fileOpen(struct ekContext *E, ekU32 argCount) { ekValue *fileValue = ekValueNullPtr; ekValue *filenameValue; ekValue *modesValue = NULL; ekFile *file; if(!ekContextGetArgs(E, argCount, "s|s", &filenameValue, &modesValue)) // assumes "r" if absent { return ekContextArgsFailure(E, argCount, "file.open([string] filename, [string] modes)"); } fileValue = ekValueCreate(E, ekValueTypeId(E, 'F')); file = (ekFile *)ekAlloc(sizeof(ekFile)); file->filename = absolutePath(E, filenameValue); // takes ownership fileValue->ptrVal = file; return fileOpenInternal(E, fileValue, modesValue); }
ekCompiler *ekCompilerCreate(struct ekContext *E) { ekCompiler *compiler = (ekCompiler *)ekAlloc(sizeof(ekCompiler)); compiler->E = E; return compiler; }