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 }
static ekBool ekRegexMatchNext(ekContext * E, ekRegex * regex, ekValue * matches) { // Why PCRE didn't make this an array of small structs is baffling to me; // it would have led to much more obvious, self-documenting code. ekS32 regexVectors[EUREKA_MAX_REGEX_VECTORS]; ekS32 len = strlen(ekValueSafeStr(regex->subject)); ekS32 err = pcre_exec(regex->regex, 0, ekValueSafeStr(regex->subject), len, regex->offset, 0, regexVectors, EUREKA_MAX_REGEX_VECTORS); if (err > 0) { ekS32 i; ekAssert(matches->type == EVT_ARRAY); for (i = 0; i < err; ++i) { ekS32 index = i * 2; ekValue * match = ekValueDonateString(E, ekSubstrdup(E, ekValueSafeStr(regex->subject), regexVectors[index], regexVectors[index + 1])); ekArrayPush(E, &matches->arrayVal, match); } regex->offset = regexVectors[1]; return ekTrue; } return ekFalse; }