📄 ejsvar.c
字号:
/******************************************************************************//* * Convert a var to a string. Store the result in ep->castTemp. If allocated * set ep->castAlloc to TRUE. Caller must NOT free the result. */char *ejsVarToString(Ejs *ep, EjsVar *vp){ MprBuf *bp; char numBuf[16]; int len, i; if (ep->castAlloc) { mprFree(ep->castTemp); } ep->castTemp = 0; ep->castAlloc = 0; switch (vp->type) { case EJS_TYPE_UNDEFINED: ep->castTemp = "undefined"; break; case EJS_TYPE_NULL: ep->castTemp = "null"; break; case EJS_TYPE_PTR: len = mprAllocSprintf(MPR_LOC_ARGS(ep), &ep->castTemp, 0, "[Opaque Pointer %p]", vp->ptr.userPtr); ep->castAlloc = 1; break; case EJS_TYPE_BOOL: if (vp->boolean) { ep->castTemp = "true"; } else { ep->castTemp = "false"; } break;#if BLD_FEATURE_FLOATING_POINT case EJS_TYPE_FLOAT: len = mprAllocSprintf(MPR_LOC_ARGS(ep), &ep->castTemp, 0, "%f", vp->floating); ep->castAlloc = 1; break;#endif case EJS_TYPE_INT: mprItoa(numBuf, sizeof(numBuf), vp->integer); ep->castTemp = mprStrdup(ep, numBuf); ep->castAlloc = 1; break;#if BLD_FEATURE_INT64 case EJS_TYPE_INT64: mprAllocSprintf(MPR_LOC_ARGS(ep), &ep->castTemp, 0, "%Ld", vp->integer64); ep->castAlloc = 1; break;#endif case EJS_TYPE_CMETHOD: ep->castTemp = "[C Method]"; break; case EJS_TYPE_STRING_CMETHOD: ep->castTemp = "[C StringMethod]"; break; case EJS_TYPE_METHOD: bp = mprCreateBuf(ep, 0, 0); mprPutStringToBuf(bp, "function ("); for (i = 0; i < vp->method.args->length; i++) { mprPutStringToBuf(bp, vp->method.args->items[i]); if ((i + 1) < vp->method.args->length) { mprPutStringToBuf(bp, ", "); } } mprPutStringToBuf(bp, ") {"); mprPutStringToBuf(bp, vp->method.body); mprPutStringToBuf(bp, "}"); mprAddNullToBuf(bp); ep->castTemp = mprStealBuf(ep, bp); ep->castAlloc = 1; mprFree(bp); break; case EJS_TYPE_OBJECT: if (ejsRunMethod(ep, vp, "toString", 0) < 0) { return mprStrdup(ep, "[object Object]"); } ep->castTemp = mprStrdup(ep, ep->result->string); ep->castAlloc = 1; break; case EJS_TYPE_STRING: if (vp->string == 0) { ep->castTemp = "null"; } else { ep->castTemp = vp->string; } break; default: mprAssert(0); } mprAssert(ep->castTemp); return ep->castTemp;}/******************************************************************************/char *ejsVarToStringEx(Ejs *ep, EjsVar *vp, bool *alloc){ char *str; mprAssert(alloc); str = ejsVarToString(ep, vp); *alloc = ep->castAlloc; ep->castAlloc = 0; ep->castTemp = 0; return str;}/******************************************************************************//* * Parse a string based on formatting instructions and intelligently * create a variable. * * Float format: [+|-]DIGITS][DIGITS][(e|E)[+|-]DIGITS] */EjsVar *ejsParseVar(Ejs *ep, const char *buf, EjsType preferredType){ EjsType type; const char *cp; int isHex; mprAssert(buf); type = preferredType; if (preferredType == EJS_TYPE_UNDEFINED) { isHex = 0; if (*buf == '-' || *buf == '+') { type = EJS_NUM_VAR; } else if (!isdigit((int) *buf)) { if (strcmp(buf, "true") == 0 || strcmp(buf, "false") == 0) { type = EJS_TYPE_BOOL; } else { type = EJS_TYPE_STRING; } } else if (isdigit((int) *buf)) { type = EJS_NUM_VAR; cp = buf; if (*cp && tolower(cp[1]) == 'x') { cp = &cp[2]; isHex = 1; for (cp = buf; *cp; cp++) { if (! isxdigit((int) *cp)) { break; } } } else {#if BLD_FEATURE_FLOATING_POINT /* Could be integer or float */ for (cp = buf; *cp; cp++) { if (! isdigit((int) *cp)) { int c = tolower(*cp); if (c == '.' || c == 'e' || c == 'f') { type = EJS_TYPE_FLOAT; break; } } }#endif } } } switch (type) { case EJS_TYPE_OBJECT: case EJS_TYPE_UNDEFINED: case EJS_TYPE_NULL: case EJS_TYPE_PTR: default: break; case EJS_TYPE_BOOL: return ejsCreateBoolVar(ep, ejsParseBoolean(buf)); case EJS_TYPE_INT: return ejsCreateIntegerVar(ep, ejsParseInteger(buf));#if BLD_FEATURE_INT64 case EJS_TYPE_INT64: return ejsCreateInteger64Var(ep, ejsParseInteger64(buf));#endif case EJS_TYPE_STRING: if (strcmp(buf, "null") == 0) { return ejsCreateNullVar(ep); } else if (strcmp(buf, "undefined") == 0) { return ejsCreateUndefinedVar(ep); } return ejsCreateStringVar(ep, buf);#if BLD_FEATURE_FLOATING_POINT case EJS_TYPE_FLOAT: return ejsCreateFloatVar(ep, atof(buf));#endif } return ejsCreateUndefinedVar(ep);}/******************************************************************************//* * Convert the variable to a number type. Only works for primitive types. */bool ejsParseBoolean(const char *s){ if (s == 0 || *s == '\0') { return 0; } if (strcmp(s, "false") == 0 || strcmp(s, "FALSE") == 0) { return 0; } return 1;}/******************************************************************************//* * Convert the variable to a number type. Only works for primitive types. */EjsNum ejsParseNumber(const char *s){#if BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_INT64 return ejsParseInteger64(s);#elif BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_FLOAT return ejsParseFloat(s);#else return ejsParseInteger(s);#endif}/******************************************************************************/#if BLD_FEATURE_INT64/* * Convert the string buffer to an Integer64. */int64 ejsParseInteger64(const char *str){ const char *cp; int64 num64; int radix, c, negative; mprAssert(str); cp = str; num64 = 0; negative = 0; if (*cp == '-') { cp++; negative = 1; } else if (*cp == '+') { cp++; } /* * Parse a number. Observe hex and octal prefixes (0x, 0) */ if (*cp != '0') { /* * Normal numbers (Radix 10) */ while (isdigit((int) *cp)) { num64 = (*cp - '0') + (num64 * 10); cp++; } } else { cp++; if (tolower(*cp) == 'x') { cp++; radix = 16; while (*cp) { c = tolower(*cp); if (isdigit(c)) { num64 = (c - '0') + (num64 * radix); } else if (c >= 'a' && c <= 'f') { num64 = (c - 'a' + 10) + (num64 * radix); } else { break; } cp++; } } else{ radix = 8; while (*cp) { c = tolower(*cp); if (isdigit(c) && c < '8') { num64 = (c - '0') + (num64 * radix); } else { break; } cp++; } } } if (negative) { return 0 - num64; } return num64;}#endif /* BLD_FEATURE_INT64 *//******************************************************************************//* * Convert the string buffer to an Integer. */int ejsParseInteger(const char *str){ const char *cp; int num; int radix, c, negative; mprAssert(str); cp = str; num = 0; negative = 0; if (*cp == '-') { cp++; negative = 1; } else if (*cp == '+') { cp++; } /* * Parse a number. Observe hex and octal prefixes (0x, 0) */ if (*cp != '0') { /* * Normal numbers (Radix 10) */ while (isdigit((int) *cp)) { num = (*cp - '0') + (num * 10); cp++; } } else { cp++; if (tolower(*cp) == 'x') { cp++; radix = 16; while (*cp) { c = tolower(*cp); if (isdigit(c)) { num = (c - '0') + (num * radix); } else if (c >= 'a' && c <= 'f') { num = (c - 'a' + 10) + (num * radix); } else { break; } cp++; } } else{ radix = 8; while (*cp) { c = tolower(*cp); if (isdigit(c) && c < '8') { num = (c - '0') + (num * radix); } else { break; } cp++; } } } if (negative) { return 0 - num; } return num;}/******************************************************************************/#if BLD_FEATURE_FLOATING_POINT/* * Convert the string buffer to an Floating. */double ejsParseFloat(const char *str){ return atof(str);}/******************************************************************************/int ejsIsNan(double f){#if WIN return _isnan(f);#elif VXWORKS /* FUTURE */ return (0);#else return (f == FP_NAN);#endif}/******************************************************************************/int ejsIsInfinite(double f){#if WIN return !_finite(f);#elif VXWORKS /* FUTURE */ return (0);#else return (f == FP_INFINITE);#endif}#endif /* BLD_FEATURE_FLOATING_POINT *//******************************************************************************//* * Single point of control for all assignment to properties. * * Copy an objects core value (only). This preserves the destination object's * name. This implements copy by reference for objects and copy by value for * strings and other types. Caller must free dest prior to calling. */static EjsVar *copyVar(EJS_LOC_DEC(ep, loc), EjsVar *dest, const EjsVar *src, EjsCopyDepth copyDepth){ Ejs *ejsContext; EjsObj *srcObj; EjsProperty *destp; const char **srcArgs; char *str; int i; mprAssert(dest); mprAssert(src); if (dest == src) { return dest; } if (dest->type != EJS_TYPE_UNDEFINED) { ejsClearVar(ep, dest); } dest->allocatedData = 0; switch (src->type) { default: case EJS_TYPE_UNDEFINED: case EJS_TYPE_NULL: break; case EJS_TYPE_BOOL: dest->boolean = src->boolean; break; case EJS_TYPE_PTR: dest->ptr = src->ptr; if (dest->ptr.destructor) { dest->allocatedData = 1; } break; case EJS_TYPE_STRING_CMETHOD: dest->cMethodWithStrings = src->cMethodWithStrings; break; case EJS_TYPE_CMETHOD: dest->cMethod = src->cMethod; break;#if BLD_FEATURE_FLOATING_POINT case EJS_TYPE_FLOAT: dest->floating = src->floating; break;#endif case EJS_TYPE_INT: dest->integer = src->integer; break;#if BLD_FEATURE_INT64 case EJS_TYPE_INT64: dest->integer64 = src->integer64; break;#endif case EJS_TYPE_OBJECT: if (copyDepth == EJS_SHALLOW_COPY) { /* * If doing a shallow copy and the src object is from the same * interpreter, or we are copying from the master interpreter, or * we are using a shared slab, then we can do a shallow copy. * Otherwise, we must do a deep copy. */ srcObj = src->objectState; if (srcObj->ejs == ep || srcObj->ejs == ep->service->master || (ep->flags & EJS_FLAGS_SHARED_SLAB)) { dest->objectState = src->objectState; dest->allocatedData = 1; break; } } /* * Doing a deep or recursive deep. Can get here if doing a shallow * copy and the object is from another non-master interpeter and not * using a shared slab. * * We must make sure the data is allocated using the right memory * context. It must be the same as the destination parent object. * Otherwise, when we free the property memory, the parent may * have a dangling pointer. */ if (dest->isProperty) { destp = ejsGetPropertyPtr(dest); if (destp->parentObj == 0) { ejsContext = ep; } else { mprAssert(destp->parentObj); ejsContext = destp->parentObj->ejs; mprAssert(ejsContext); } } else { ejsContext = ep; } dest->objectState = createObj(EJS_LOC_PASS(ejsContext, loc)); if (dest->objectState == 0) { /* Memory Error */ return 0; } dest->objectState->baseClass = src->objectState->baseClass; dest->objectState->methods = src->objectState->methods; dest->objectState->noConstructor = src->objectState->noConstructor; dest->objectState->objName = mprStrdup(ejsContext, src->objectState->objName); if (dest->objectState->objName == 0) { return 0; } if (ejsCopyProperties(ep, dest, src, copyDepth) == 0) { return 0; } dest->allocatedData = 1; break; case EJS_TYPE_METHOD: dest->method.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS); if (dest->method.args == 0) { return 0; } dest->allocatedData = 1; if (src->method.args) { srcArgs = (const char**) src->method.args->items; for (i = 0; i < src->method.args->length; i++) { str = mprStrdupInternal(EJS_LOC_PASS(dest->method.args, loc), srcArgs[i]); if (str == 0) { mprFree(dest->method.args); dest->method.args = 0; return 0; } if (mprAddItem(dest->method.args, str) < 0) { mprFree(dest->method.args); dest->method.args = 0; return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -