Beispiel #1
0
static ekU32 regexGMatch(struct ekContext * E, ekU32 argCount)
{
    ekRegex * regex = regexCreateMatchFromArgs(E, argCount, "re.gmatch([string] subject, [string] pattern, [optional string] options)");
    if (regex) {
        ekValue * closure = ekValueCreateCFunction(E, regexGMatchIterator);
        ekValue * regexValue = ekValueCreate(E, ekValueTypeId(E, 'R'));
        regexValue->ptrVal = regex;
        closure->closureVars = ekMapCreate(E, EMKT_STRING);
        ekMapGetS2P(E, closure->closureVars, "regex") = regexValue;
        ekContextReturn(E, closure);
    }
    ekContextReturn(E, ekValueNullPtr);
}
Beispiel #2
0
static ekU32 fileWrite(struct ekContext *E, ekU32 argCount)
{
    ekValue *thisValue;
    ekValue *ret = ekValueNullPtr;
    ekValue *dataValue = NULL;
    ekFile *file;

    if(!ekContextGetArgs(E, argCount, "*Fs", &thisValue, &dataValue))
    {
        return ekContextArgsFailure(E, argCount, "file.write([string] data)");
    }

    file = (ekFile *)thisValue->ptrVal;

    if((file->state != EFS_WRITE) && (file->state != EFS_APPEND))
    {
        switchState(E, file, EFS_WRITE);
    }
    if(file->handle)
    {
        const char *data = ekValueSafeStr(dataValue);
        int len = strlen(data);
        int bytesWritten = fwrite(data, 1, len, file->handle);
        if(bytesWritten == len)
        {
            ret = ekValueCreateInt(E, 1);
        }
    }
    ekValueRemoveRefNote(E, thisValue, "fileWrite no longer needs thisValue");
    ekContextReturn(E, ret); // will be true if we successfully wrote
}
Beispiel #3
0
static ekU32 fileSize(struct ekContext *E, ekU32 argCount)
{
    ekValue *ret = ekValueNullPtr;
    ekValue *filenameValue;
    ekFile *file;
    struct stat s;

    if(!ekContextGetArgs(E, argCount, "s", &filenameValue))
    {
        return ekContextArgsFailure(E, argCount, "file.size(path)");
    }

    if(stat(ekValueSafeStr(file->filename), &s) != -1)
    {
        if(S_ISDIR(s.st_mode))
        {
            return ekContextArgsFailure(E, 0, "file.size() does not work on directories");
        }
        else
        {
            ret = ekValueCreateInt(E, s.st_size);
        }
    }

    ekValueRemoveRefNote(E, filenameValue, "fileSize doesnt need filename anymore");
    ekContextReturn(E, ret);
}
Beispiel #4
0
static ekU32 fileLs(struct ekContext *E, ekU32 argCount)
{
    ekValue *filenameValue = NULL;
    ekValue *arrayValue = NULL;

    if(!ekContextGetArgs(E, argCount, "s", &filenameValue))
    {
        return ekContextArgsFailure(E, argCount, "file.ls(dirpath)");
    }

    arrayValue = ekValueCreateArray(E);

#ifdef USE_DIRENT
    {
        DIR *dir = opendir(ekValueSafeStr(filenameValue));
        if(dir)
        {
            struct dirent *entry;
            while((entry = readdir(dir)) != NULL)
            {
                if(strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
                {
                    ekValueArrayPush(E, arrayValue, ekValueCreateString(E, entry->d_name));
                }
            }
            closedir(dir);
        }
    }
#endif

    ekValueRemoveRefNote(E, filenameValue, "fileExists doesnt need filename anymore");
    ekContextReturn(E, arrayValue);
}
Beispiel #5
0
static ekU32 fileMemberSize(struct ekContext *E, ekU32 argCount)
{
    ekValue *thisValue;
    ekValue *ret = ekValueNullPtr;
    ekFile *file;

    if(!ekContextGetArgs(E, argCount, "*F", &thisValue))
    {
        return ekContextArgsFailure(E, argCount, "file.size()");
    }

    file = (ekFile *)thisValue->ptrVal;

    if(file->handle)
    {
        int end;
        int currentPos = ftell(file->handle);
        fseek(file->handle, 0, SEEK_END);
        end = ftell(file->handle);
        fseek(file->handle, currentPos, SEEK_SET);
        ret = ekValueCreateInt(E, end);
    }

    ekValueRemoveRefNote(E, thisValue, "fileMemberSize doesnt need this anymore");
    ekContextReturn(E, ret);
}
Beispiel #6
0
static ekU32 fileIterate(struct ekContext *E, ekU32 argCount)
{
    ekValue *thisValue;
    ekValue *ret = ekValueNullPtr;
    ekValue *chompValue = NULL;
    ekFile *file;
    ekValue *closure;

    if(!ekContextGetArgs(E, argCount, "*F|?", &thisValue, &chompValue))
    {
        return ekContextArgsFailure(E, argCount, "file.iterate([optional bool] chompNewline)");
    }

    file = (ekFile *)thisValue->ptrVal;

    if(chompValue)
    {
        chompValue = ekValueToBool(E, chompValue);
    }
    else
    {
        chompValue = ekValueCreateInt(E, 0);
    }

    closure = ekValueCreateCFunction(E, fileIterator);
    closure->closureVars = ekMapCreate(E, EMKT_STRING);
    ekMapGetS2P(E, closure->closureVars, "file") = thisValue;
    ekMapGetS2P(E, closure->closureVars, "chomp") = chompValue;
    ekContextReturn(E, closure);
}
Beispiel #7
0
static ekU32 regexSubInternal(struct ekContext * E, ekU32 argCount, ekBool forceGlobal)
{
    ekValue * subject = NULL;
    ekValue * pattern = NULL;
    ekValue * replace = NULL;
    ekValue * options = NULL;
    ekValue * result = ekValueNullPtr;
    ekRegex * regex;
    int count = 0;

    if (!ekContextGetArgs(E, argCount, "sss|s", &subject, &pattern, &replace, &options)) {
        return ekContextArgsFailure(E, argCount, "re.sub([string] subject, [string] pattern, [string] replacement, [optional string] options)");
    }

    result = ekValueCreateString(E, "");
    regex = ekRegexCreate(E, subject, pattern, options);
    if (forceGlobal) {
        regex->global = ekTrue;
    }
    if (regex) {
        count = ekRegexSub(E, regex, replace, &result->stringVal);
        ekRegexDestroy(E, regex);
    }
    ekContextReturn(E, result);
}
Beispiel #8
0
static ekU32 fileLines(struct ekContext *E, ekU32 argCount)
{
    ekValue *thisValue;
    ekValue *ret = ekValueNullPtr;
    ekValue *lineValue;
    ekValue *chompValue = NULL;
    ekBool chomp = ekFalse;
    ekFile *file;

    if(!ekContextGetArgs(E, argCount, "*F|?", &thisValue, &chompValue))
    {
        return ekContextArgsFailure(E, argCount, "file.lines([optional bool] chompNewline)");
    }

    file = (ekFile *)thisValue->ptrVal;
    if(chompValue)
    {
        chompValue = ekValueToBool(E, chompValue);
        chomp = chompValue->boolVal;
        ekValueRemoveRefNote(E, chompValue, "chompValue temporary no longer needed");
    }

    switchState(E, file, EFS_READ);

    ret = ekValueCreateArray(E);
    while((lineValue = readLineInternal(E, file, chomp)) != ekValueNullPtr)
    {
        ekValueArrayPush(E, ret, lineValue);
    }

    ekValueRemoveRefNote(E, thisValue, "lines no longer needs thisValue");
    ekContextReturn(E, ret); // will be the data if we succesfully read
}
Beispiel #9
0
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
}
Beispiel #10
0
static ekU32 regexMatch(struct ekContext * E, ekU32 argCount)
{
    ekValue * results = ekValueNullPtr;
    ekRegex * regex = regexCreateMatchFromArgs(E, argCount, "re.match([string] subject, [string] pattern, [optional string] options)");
    if (regex) {
        results = ekValueCreateArray(E);
        if (!ekRegexMatchNext(E, regex, results)) {
            results = ekValueNullPtr;
        }
        ekRegexDestroy(E, regex);
    }
    ekContextReturn(E, results);
}
Beispiel #11
0
static ekU32 fileAbs(struct ekContext *E, ekU32 argCount)
{
    ekValue *filenameValue = NULL;
    struct stat s;
    int exists = 0;

    if(!ekContextGetArgs(E, argCount, "s", &filenameValue))
    {
        return ekContextArgsFailure(E, argCount, "file.exists(path)");
    }

    filenameValue = absolutePath(E, filenameValue);

    ekContextReturn(E, filenameValue);
}
Beispiel #12
0
static ekU32 fileCreateIterator(struct ekContext *E, ekU32 argCount)
{
    ekValue *thisValue = NULL;
    ekValue *closure;

    if(!ekContextGetArgs(E, argCount, "F", &thisValue))
    {
        return ekContextArgsFailure(E, argCount, "file iterator missing argument");
    }

    closure = ekValueCreateCFunction(E, fileIterator);
    closure->closureVars = ekMapCreate(E, EMKT_STRING);
    ekMapGetS2P(E, closure->closureVars, "file") = thisValue;
    ekMapGetS2P(E, closure->closureVars, "chomp") = ekValueCreateInt(E, 0);
    ekContextReturn(E, closure);
}
Beispiel #13
0
// feeds one readline() at a time
static ekU32 fileIterator(struct ekContext *E, ekU32 argCount)
{
    ekFrame *frame = ekArrayTop(E, &E->frames);
    ekValue *fileVal;
    ekValue *chompVal;
    ekFile *file;

    ekAssert(frame->closure && frame->closure->closureVars);
    fileVal = ekMapGetS2P(E, frame->closure->closureVars, "file");
    chompVal = ekMapGetS2P(E, frame->closure->closureVars, "chomp");
    ekAssert(argCount == 0);
    ekContextPopValues(E, argCount);
    file = (ekFile *)fileVal->ptrVal;
    switchState(E, file, EFS_READ);
    ekContextReturn(E, readLineInternal(E, file, chompVal->intVal));
}
Beispiel #14
0
static ekU32 fileOpenInternal(struct ekContext *E, ekValue *fileValue, ekValue *modesValue)
{
    ekValue *ret = ekValueNullPtr;
    ekFile *file = (ekFile *)fileValue->ptrVal;
    if(isDir(E, file->filename))
    {
        return ekContextArgsFailure(E, 0, "file.open() does not work on directories");
    }

    {
        const char *c;
        const char *modes = "r";
        int state = EFS_READ;
        if(modesValue)
        {
            modes = ekValueSafeStr(modesValue);
        }
        for(c = modes; *c; ++c)
        {
            switch(*c)
            {
                case 'r':
                    state = EFS_READ;
                    break;
                case 'w':
                    state = EFS_WRITE;
                    break;
                case 'a':
                    state = EFS_APPEND;
                    break;
            };
        }

        switchState(E, file, state);
        if(file->handle)
        {
            ret = fileValue;
        }
        else
        {
            ekValueRemoveRefNote(E, fileValue, "fileOpen failed, so forget about fileValue");
        }
    }

    ekContextReturn(E, ret);
}
Beispiel #15
0
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);
}
Beispiel #16
0
static ekU32 regexGMatchIterator(struct ekContext * E, ekU32 argCount)
{
    ekFrame * frame = ekArrayTop(E, &E->frames);
    ekValue * regexValue;
    ekRegex * regex;
    ekValue * results;

    ekAssert(frame->closure && frame->closure->closureVars);
    regexValue = ekMapGetS2P(E, frame->closure->closureVars, "regex");
    regex = (ekRegex *)regexValue->ptrVal;

    ekAssert(argCount == 0);
    ekContextPopValues(E, argCount);

    results = ekValueCreateArray(E);
    if (!ekRegexMatchNext(E, regex, results)) {
        results = ekValueNullPtr;
    }

    ekContextReturn(E, results);
}
Beispiel #17
0
static ekU32 fileClose(struct ekContext *E, ekU32 argCount)
{
    ekValue *thisValue;
    ekValue *ret = ekValueNullPtr;
    ekValue *filenameValue;
    ekFile *file;

    if(!ekContextGetArgs(E, argCount, "*F", &thisValue))
    {
        return ekContextArgsFailure(E, argCount, "file.close()");
    }

    file = (ekFile *)thisValue->ptrVal;

    if(switchState(E, file, EFS_CLOSED))
    {
        ret = ekValueCreateInt(E, 1);
    }

    ekValueRemoveRefNote(E, thisValue, "fileClose doesnt need this anymore");
    ekContextReturn(E, ret);
}