⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jim.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
    objPtr->nextObjPtr = interp->liveList;
    if (interp->liveList)
        interp->liveList->prevObjPtr = objPtr;
    interp->liveList = objPtr;

    return objPtr;
}

/* Free an object. Actually objects are never freed, but
 * just moved to the free objects list, where they will be
 * reused by Jim_NewObj(). */
void Jim_FreeObj(Jim_Interp *interp, Jim_Obj *objPtr)
{
    /* Check if the object was already freed, panic. */
    if (objPtr->refCount != 0)  {
        Jim_Panic(interp,"!!!Object %p freed with bad refcount %d", objPtr,
                objPtr->refCount);
    }
    /* Free the internal representation */
    Jim_FreeIntRep(interp, objPtr);
    /* Free the string representation */
    if (objPtr->bytes != NULL) {
        if (objPtr->bytes != JimEmptyStringRep)
            Jim_Free(objPtr->bytes);
    }
    /* Unlink the object from the live objects list */
    if (objPtr->prevObjPtr)
        objPtr->prevObjPtr->nextObjPtr = objPtr->nextObjPtr;
    if (objPtr->nextObjPtr)
        objPtr->nextObjPtr->prevObjPtr = objPtr->prevObjPtr;
    if (interp->liveList == objPtr)
        interp->liveList = objPtr->nextObjPtr;
    /* Link the object into the free objects list */
    objPtr->prevObjPtr = NULL;
    objPtr->nextObjPtr = interp->freeList;
    if (interp->freeList)
        interp->freeList->prevObjPtr = objPtr;
    interp->freeList = objPtr;
    objPtr->refCount = -1;
}

/* Invalidate the string representation of an object. */
void Jim_InvalidateStringRep(Jim_Obj *objPtr)
{
    if (objPtr->bytes != NULL) {
        if (objPtr->bytes != JimEmptyStringRep)
            Jim_Free(objPtr->bytes);
    }
    objPtr->bytes = NULL;
}

#define Jim_SetStringRep(o, b, l) \
    do { (o)->bytes = b; (o)->length = l; } while (0)

/* Set the initial string representation for an object.
 * Does not try to free an old one. */
void Jim_InitStringRep(Jim_Obj *objPtr, const char *bytes, int length)
{
    if (length == 0) {
        objPtr->bytes = JimEmptyStringRep;
        objPtr->length = 0;
    } else {
        objPtr->bytes = Jim_Alloc(length+1);
        objPtr->length = length;
        memcpy(objPtr->bytes, bytes, length);
        objPtr->bytes[length] = '\0';
    }
}

/* Duplicate an object. The returned object has refcount = 0. */
Jim_Obj *Jim_DuplicateObj(Jim_Interp *interp, Jim_Obj *objPtr)
{
    Jim_Obj *dupPtr;

    dupPtr = Jim_NewObj(interp);
    if (objPtr->bytes == NULL) {
        /* Object does not have a valid string representation. */
        dupPtr->bytes = NULL;
    } else {
        Jim_InitStringRep(dupPtr, objPtr->bytes, objPtr->length);
    }
    if (objPtr->typePtr != NULL) {
        if (objPtr->typePtr->dupIntRepProc == NULL) {
            dupPtr->internalRep = objPtr->internalRep;
        } else {
            objPtr->typePtr->dupIntRepProc(interp, objPtr, dupPtr);
        }
        dupPtr->typePtr = objPtr->typePtr;
    } else {
        dupPtr->typePtr = NULL;
    }
    return dupPtr;
}

/* Return the string representation for objPtr. If the object
 * string representation is invalid, calls the method to create
 * a new one starting from the internal representation of the object. */
const char *Jim_GetString(Jim_Obj *objPtr, int *lenPtr)
{
    if (objPtr->bytes == NULL) {
        /* Invalid string repr. Generate it. */
        if (objPtr->typePtr->updateStringProc == NULL) {
            Jim_Panic(NULL,"UpdataStringProc called against '%s' type.",
                objPtr->typePtr->name);
        }
        objPtr->typePtr->updateStringProc(objPtr);
    }
    if (lenPtr)
        *lenPtr = objPtr->length;
    return objPtr->bytes;
}

/* Just returns the length of the object's string rep */
int Jim_Length(Jim_Obj *objPtr)
{
    int len;

    Jim_GetString(objPtr, &len);
    return len;
}

/* -----------------------------------------------------------------------------
 * String Object
 * ---------------------------------------------------------------------------*/
static void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr);
static int SetStringFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr);

static Jim_ObjType stringObjType = {
    "string",
    NULL,
    DupStringInternalRep,
    NULL,
    JIM_TYPE_REFERENCES,
};

void DupStringInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr)
{
    JIM_NOTUSED(interp);

    /* This is a bit subtle: the only caller of this function
     * should be Jim_DuplicateObj(), that will copy the
     * string representaion. After the copy, the duplicated
     * object will not have more room in teh buffer than
     * srcPtr->length bytes. So we just set it to length. */
    dupPtr->internalRep.strValue.maxLength = srcPtr->length;
}

int SetStringFromAny(Jim_Interp *interp, Jim_Obj *objPtr)
{
    /* Get a fresh string representation. */
    (void) Jim_GetString(objPtr, NULL);
    /* Free any other internal representation. */
    Jim_FreeIntRep(interp, objPtr);
    /* Set it as string, i.e. just set the maxLength field. */
    objPtr->typePtr = &stringObjType;
    objPtr->internalRep.strValue.maxLength = objPtr->length;
    return JIM_OK;
}

Jim_Obj *Jim_NewStringObj(Jim_Interp *interp, const char *s, int len)
{
    Jim_Obj *objPtr = Jim_NewObj(interp);

    if (len == -1)
        len = strlen(s);
    /* Alloc/Set the string rep. */
    if (len == 0) {
        objPtr->bytes = JimEmptyStringRep;
        objPtr->length = 0;
    } else {
        objPtr->bytes = Jim_Alloc(len+1);
        objPtr->length = len;
        memcpy(objPtr->bytes, s, len);
        objPtr->bytes[len] = '\0';
    }

    /* No typePtr field for the vanilla string object. */
    objPtr->typePtr = NULL;
    return objPtr;
}

/* This version does not try to duplicate the 's' pointer, but
 * use it directly. */
Jim_Obj *Jim_NewStringObjNoAlloc(Jim_Interp *interp, char *s, int len)
{
    Jim_Obj *objPtr = Jim_NewObj(interp);

    if (len == -1)
        len = strlen(s);
    Jim_SetStringRep(objPtr, s, len);
    objPtr->typePtr = NULL;
    return objPtr;
}

/* Low-level string append. Use it only against objects
 * of type "string". */
void StringAppendString(Jim_Obj *objPtr, const char *str, int len)
{
    int needlen;

    if (len == -1)
        len = strlen(str);
    needlen = objPtr->length + len;
    if (objPtr->internalRep.strValue.maxLength < needlen ||
        objPtr->internalRep.strValue.maxLength == 0) {
        if (objPtr->bytes == JimEmptyStringRep) {
            objPtr->bytes = Jim_Alloc((needlen*2)+1);
        } else {
            objPtr->bytes = Jim_Realloc(objPtr->bytes, (needlen*2)+1);
        }
        objPtr->internalRep.strValue.maxLength = needlen*2;
    }
    memcpy(objPtr->bytes + objPtr->length, str, len);
    objPtr->bytes[objPtr->length+len] = '\0';
    objPtr->length += len;
}

/* Low-level wrapper to append an object. */
void StringAppendObj(Jim_Obj *objPtr, Jim_Obj *appendObjPtr)
{
    int len;
    const char *str;

    str = Jim_GetString(appendObjPtr, &len);
    StringAppendString(objPtr, str, len);
}

/* Higher level API to append strings to objects. */
void Jim_AppendString(Jim_Interp *interp, Jim_Obj *objPtr, const char *str,
        int len)
{
    if (Jim_IsShared(objPtr))
        Jim_Panic(interp,"Jim_AppendString called with shared object");
    if (objPtr->typePtr != &stringObjType)
        SetStringFromAny(interp, objPtr);
    StringAppendString(objPtr, str, len);
}

void Jim_AppendObj(Jim_Interp *interp, Jim_Obj *objPtr,
        Jim_Obj *appendObjPtr)
{
    int len;
    const char *str;

    str = Jim_GetString(appendObjPtr, &len);
    Jim_AppendString(interp, objPtr, str, len);
}

void Jim_AppendStrings(Jim_Interp *interp, Jim_Obj *objPtr, ...)
{
    va_list ap;

    if (objPtr->typePtr != &stringObjType)
        SetStringFromAny(interp, objPtr);
    va_start(ap, objPtr);
    while (1) {
        char *s = va_arg(ap, char*);

        if (s == NULL) break;
        Jim_AppendString(interp, objPtr, s, -1);
    }
    va_end(ap);
}

int Jim_StringEqObj(Jim_Obj *aObjPtr, Jim_Obj *bObjPtr, int nocase)
{
    const char *aStr, *bStr;
    int aLen, bLen, i;

    if (aObjPtr == bObjPtr) return 1;
    aStr = Jim_GetString(aObjPtr, &aLen);
    bStr = Jim_GetString(bObjPtr, &bLen);
    if (aLen != bLen) return 0;
    if (nocase == 0)
        return memcmp(aStr, bStr, aLen) == 0;
    for (i = 0; i < aLen; i++) {
        if (tolower((int)aStr[i]) != tolower((int)bStr[i]))
            return 0;
    }
    return 1;
}

int Jim_StringMatchObj(Jim_Obj *patternObjPtr, Jim_Obj *objPtr,
        int nocase)
{
    const char *pattern, *string;
    int patternLen, stringLen;

    pattern = Jim_GetString(patternObjPtr, &patternLen);
    string = Jim_GetString(objPtr, &stringLen);
    return JimStringMatch(pattern, patternLen, string, stringLen, nocase);
}

int Jim_StringCompareObj(Jim_Obj *firstObjPtr,
        Jim_Obj *secondObjPtr, int nocase)
{
    const char *s1, *s2;
    int l1, l2;

    s1 = Jim_GetString(firstObjPtr, &l1);
    s2 = Jim_GetString(secondObjPtr, &l2);
    return JimStringCompare(s1, l1, s2, l2, nocase);
}

/* Convert a range, as returned by Jim_GetRange(), into
 * an absolute index into an object of the specified length.
 * This function may return negative values, or values
 * bigger or equal to the length of the list if the index
 * is out of range. */
static int JimRelToAbsIndex(int len, int index)
{
    if (index < 0)
        return len + index;
    return index;
}

/* Convert a pair of index as normalize by JimRelToAbsIndex(),
 * into a range stored in *firstPtr, *lastPtr, *rangeLenPtr, suitable
 * for implementation of commands like [string range] and [lrange].
 *
 * The resulting range is guaranteed to address valid elements of
 * the structure. */
static void JimRelToAbsRange(int len, int first, int last,
        int *firstPtr, int *lastPtr, int *rangeLenPtr)
{
    int rangeLen;

    if (first > last) {
        rangeLen = 0;
    } else {
        rangeLen = last-first+1;
        if (rangeLen) {
            if (first < 0) {
                rangeLen += first;
                first = 0;
            }
            if (last >= len) {
                rangeLen -= (last-(len-1));
                last = len-1;
            }
        }
    }
    if (rangeLen < 0) rangeLen = 0;

    *firstPtr = first;
    *lastPtr = last;
    *rangeLenPtr = rangeLen;
}

Jim_Obj *Jim_StringRangeObj(Jim_Interp *interp,
        Jim_Obj *strObjPtr, Jim_Obj *firstObjPtr, Jim_Obj *lastObjPtr)
{
    int first, last;
    const char *str;
    int len, rangeLen;

    if (Jim_GetIndex(interp, firstObjPtr, &first) != JIM_OK ||
        Jim_GetIndex(interp, lastObjPtr, &last) != JIM_OK)
        return NULL;
    str = Jim_GetString(strObjPtr, &len);
    first = JimRelToAbsIndex(len, first);
    last = JimRelToAbsIndex(len, last);
    JimRelToAbsRange(len, first, last, &first, &last, &rangeLen);
    return Jim_NewStringObj(interp, str+first, rangeLen);
}

static Jim_Obj *JimStringToLower(Jim_Interp *interp, Jim_Obj *strObjPtr)
{
    char *buf = Jim_Alloc(strObjPtr->length+1);
    int i;

    memcpy(buf, strObjPtr->bytes, strObjPtr->length+1);
    for (i = 0; i < strObjPtr->length; i++)
        buf[i] = tolower(buf[i]);
    return Jim_NewStringObjNoAlloc(interp, buf, strObjPtr->length);
}

static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr)
{
    char *buf = Jim_Alloc(strObjPtr->length+1);
    int i;

    memcpy(buf, strObjPtr->bytes, strObjPtr->length+1);
    for (i = 0; i < strObjPtr->length; i++)
        buf[i] = toupper(buf[i]);
    return Jim_NewStringObjNoAlloc(interp, buf, strObjPtr->length);
}

/* This is the core of the [format] command.
 * TODO: Export it, make it real... for now only %s and %%
 * specifiers supported. */
Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
        int objc, Jim_Obj *const *objv)
{
    const char *fmt;
    int fmtLen;
    Jim_Obj *resObjPtr;

    fmt = Jim_GetString(fmtObjPtr, &fmtLen);
    resObjPtr = Jim_NewStringObj(interp, "", 0);
    while (fmtLen) {
        const char *p = fmt;
        char spec[2], c;
        jim_wide wideValue;

        while (*fmt != '%' && fmtLen) {
            fmt++; fmtLen--;
        }
        Jim_AppendString(interp, resObjPtr, p, fmt-p);
        if (fmtLen == 0)
            break;
        fmt++; fmtLen--; /* skip '%' */
        if (*fmt != '%') {
            if (objc == 0) {
                Jim_FreeNewObj(interp, resObjPtr);
                Jim_SetResultString(interp,
                        "not enough arguments for all format specifiers", -1);
                return NULL;
            } else {
                objc--;
            }
        }
        switch(*fmt) {
        case 's':
            Jim_AppendObj(interp, resObjPtr, objv[0]);
            objv++;
            break;
        case 'c':
            if (Jim_GetWide(interp, objv[0], &wideValue) == JIM_ERR) {
                Jim_FreeNewObj(interp, resObjPtr);
                return NULL;
            }
            c = (char) wideValue;
            Jim_AppendString(interp, resO

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -