Ejemplo n.º 1
0
/* match: search for regexp anywhere in text */
static JsVar *match(char *regexp, JsVar *str, size_t startIndex, bool ignoreCase) {
  matchInfo info;
  info.sourceStr = str;
  info.startIndex = startIndex;
  info.ignoreCase = ignoreCase;
  info.rangeMatch = false;
  info.rangeFirstChar = NO_RANGE;
  info.groups = 0;

  JsVar *rmatch;
  JsvStringIterator txtIt, txtIt2;
  jsvStringIteratorNew(&txtIt, str, startIndex);
  /* must look even if string is empty */
  txtIt2 = jsvStringIteratorClone(&txtIt);
  rmatch = matchhere(regexp, &txtIt2, info);
  jsvStringIteratorFree(&txtIt2);
  jsvStringIteratorNext(&txtIt);
  while (!rmatch && jsvStringIteratorHasChar(&txtIt)) {
    info.startIndex++;
    txtIt2 = jsvStringIteratorClone(&txtIt);
    rmatch = matchhere(regexp, &txtIt2, info);
    jsvStringIteratorFree(&txtIt2);
    jsvStringIteratorNext(&txtIt);
  }
  jsvStringIteratorFree(&txtIt);
  return rmatch;
}
Ejemplo n.º 2
0
JsVar *jslNewStringFromLexer(JslCharPos *charFrom, size_t charTo) {
  // Original method - just copy it verbatim
  size_t maxLength = charTo + 1 - jsvStringIteratorGetIndex(&charFrom->it);
  assert(maxLength>0); // will fail if 0
  // Try and create a flat string first
  JsVar *var = 0;
  if (maxLength > JSV_FLAT_STRING_BREAK_EVEN) {
    var = jsvNewFlatStringOfLength((unsigned int)maxLength);
    if (var) {
      // Flat string
      char *flatPtr = jsvGetFlatStringPointer(var);
      *(flatPtr++) = charFrom->currCh;
      JsvStringIterator it = jsvStringIteratorClone(&charFrom->it);
      while (jsvStringIteratorHasChar(&it) && (--maxLength>0)) {
        *(flatPtr++) = jsvStringIteratorGetChar(&it);
        jsvStringIteratorNext(&it);
      }
      jsvStringIteratorFree(&it);
      return var;
    }
  }
  // Non-flat string...
  var = jsvNewFromEmptyString();
  if (!var) { // out of memory
    return 0;
  }

  //jsvAppendStringVar(var, lex->sourceVar, charFrom->it->index, (int)(charTo-charFrom));
  JsVar *block = jsvLockAgain(var);
  block->varData.str[0] = charFrom->currCh;
  size_t blockChars = 1;

  size_t l = maxLength;
  // now start appending
  JsvStringIterator it = jsvStringIteratorClone(&charFrom->it);
  while (jsvStringIteratorHasChar(&it) && (--maxLength>0)) {
    char ch = jsvStringIteratorGetChar(&it);
    if (blockChars >= jsvGetMaxCharactersInVar(block)) {
      jsvSetCharactersInVar(block, blockChars);
      JsVar *next = jsvNewWithFlags(JSV_STRING_EXT_0);
      if (!next) break; // out of memory
      // we don't ref, because  StringExts are never reffed as they only have one owner (and ALWAYS have an owner)
      jsvSetLastChild(block, jsvGetRef(next));
      jsvUnLock(block);
      block = next;
      blockChars=0; // it's new, so empty
    }
    block->varData.str[blockChars++] = ch;
    jsvStringIteratorNext(&it);
  }
  jsvSetCharactersInVar(block, blockChars);
  jsvUnLock(block);
  // Just make sure we only assert if there's a bug here. If we just ran out of memory or at end of string it's ok
  assert((l == jsvGetStringLength(var)) || (jsErrorFlags&JSERR_MEMORY) || !jsvStringIteratorHasChar(&it));
  jsvStringIteratorFree(&it);


  return var;
}
Ejemplo n.º 3
0
size_t httpStringGet(JsVar *v, char *str, size_t len) {
    size_t l = len;
    JsvStringIterator it;
    jsvStringIteratorNew(&it, v, 0);
    while (jsvStringIteratorHasChar(&it)) {
        if (l--==0) {
            jsvStringIteratorFree(&it);
            return len;
        }
        *(str++) = jsvStringIteratorGetChar(&it);
        jsvStringIteratorNext(&it);
    }
    jsvStringIteratorFree(&it);
    return len-l;
}
Ejemplo n.º 4
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "trim",
  "generate" : "jswrap_string_trim",
  "return" : ["JsVar","A String with Whitespace removed from the beginning and end"],
  "return_object" : "String"
}
Return a new string with any whitespace (tabs, space, form feed, newline,
carriage return, etc) removed from the beginning and end.
 */
JsVar *jswrap_string_trim(JsVar *parent) {
  JsVar *s = jsvAsString(parent);
  if (!s) return s;
  unsigned int start = 0;
  int end = -1;

  // work out beginning and end
  JsvStringIterator it;
  jsvStringIteratorNew(&it, s, 0);
  while (jsvStringIteratorHasChar(&it)) {
    bool ws = isWhitespace(jsvStringIteratorGetChar(&it));
    if (!ws) {
      if (end<0) start = (unsigned int)jsvStringIteratorGetIndex(&it);
      end = (int)jsvStringIteratorGetIndex(&it); // last
    }
    jsvStringIteratorNext(&it);
  }
  jsvStringIteratorFree(&it);
  // work out length
  unsigned int len = 0;
  if (end>=(int)start) len = 1+(unsigned int)end-start;
  JsVar *res = jsvNewFromStringVar(s, start, len);
  jsvUnLock(s);
  return res;
}
Ejemplo n.º 5
0
void jslSeekTo(JsLex *lex, size_t seekToChar) {
  jsvStringIteratorFree(&lex->it);
  jsvStringIteratorNew(&lex->it, lex->sourceVar, seekToChar);
  lex->tokenStart.it.var = 0;
  lex->tokenStart.currCh = 0;
  jslPreload(lex);
}
Ejemplo n.º 6
0
/*JSON{
  "type" : "method",
  "class" : "OneWire",
  "name" : "select",
  "generate" : "jswrap_onewire_select",
  "params" : [
    ["rom","JsVar","The device to select (get this using `OneWire.search()`)"]
  ]
}
Select a ROM - always performs a reset first
 */
void jswrap_onewire_select(JsVar *parent, JsVar *rom) {
  Pin pin = onewire_getpin(parent);
  if (!jshIsPinValid(pin)) return;
  if (!jsvIsString(rom) || jsvGetStringLength(rom)!=16) {
    jsExceptionHere(JSET_TYPEERROR, "Invalid OneWire device address %q", rom);
    return;
  }

  // perform a reset
  OneWireReset(pin);

  // decode the address
  unsigned long long romdata = 0;
  JsvStringIterator it;
  jsvStringIteratorNew(&it, rom, 0);
  int i;
  for (i=0;i<8;i++) {
    char b[3];
    b[0] = jsvStringIteratorGetChar(&it);
    jsvStringIteratorNext(&it);
    b[1] = jsvStringIteratorGetChar(&it);
    jsvStringIteratorNext(&it);
    b[2] = 0;
    romdata = romdata | (((unsigned long long)stringToIntWithRadix(b,16,NULL,NULL)) << (i*8));

  }
  jsvStringIteratorFree(&it);

  // finally write data out
  OneWireWrite(pin, 8, 0x55);
  OneWireWrite(pin, 64, romdata);
}
Ejemplo n.º 7
0
void jsvArrayBufferIteratorSetValueAndRewind(JsvArrayBufferIterator *it, JsVar *value) {
  JsvStringIterator oldIt = jsvStringIteratorClone(&it->it);
  jsvArrayBufferIteratorSetValue(it, value);
  jsvStringIteratorFree(&it->it);
  it->it = oldIt;
  it->hasAccessedElement = false;
}
Ejemplo n.º 8
0
void jsvIteratorFree(JsvIterator *it) {
  switch (it->type) {
  case JSVI_OBJECT : jsvObjectIteratorFree(&it->it.obj); break;
  case JSVI_STRING : jsvStringIteratorFree(&it->it.str); break;
  case JSVI_ARRAYBUFFER : jsvArrayBufferIteratorFree(&it->it.buf); break;
  default: assert(0); break;
  }
}
Ejemplo n.º 9
0
void jslSeekToP(JsLex *lex, JslCharPos *seekToChar) {
  jsvStringIteratorFree(&lex->it);
  lex->it = jsvStringIteratorClone(&seekToChar->it);
  lex->currCh = seekToChar->currCh;
  lex->tokenStart.it.var = 0;
  lex->tokenStart.currCh = 0;
  jslGetNextToken(lex);
}
Ejemplo n.º 10
0
JsVar *jsvArrayBufferIteratorGetValueAndRewind(JsvArrayBufferIterator *it) {
  JsvStringIterator oldIt = jsvStringIteratorClone(&it->it);
  JsVar *v = jsvArrayBufferIteratorGetValue(it);
  jsvStringIteratorFree(&it->it);
  it->it = oldIt;
  it->hasAccessedElement = false;
  return v;
}
Ejemplo n.º 11
0
void jsvIteratorFree(JsvIterator *it) {
  switch (it->type) {
  case JSVI_FULLARRAY: jsvUnLock(it->it.obj.var); // intentionally no break
  case JSVI_OBJECT : jsvObjectIteratorFree(&it->it.obj.it); break;
  case JSVI_STRING : jsvStringIteratorFree(&it->it.str); break;
  case JSVI_ARRAYBUFFER : jsvArrayBufferIteratorFree(&it->it.buf); break;
  default: assert(0); break;
  }
}
Ejemplo n.º 12
0
void jslSeekTo(size_t seekToChar) {
  if (lex->it.var) jsvLockAgain(lex->it.var); // see jslGetNextCh
  jsvStringIteratorFree(&lex->it);
  jsvStringIteratorNew(&lex->it, lex->sourceVar, seekToChar);
  jsvUnLock(lex->it.var); // see jslGetNextCh
  lex->tokenStart.it.var = 0;
  lex->tokenStart.currCh = 0;
  jslPreload();
}
Ejemplo n.º 13
0
void jsvStringIteratorAppendString(JsvStringIterator *it, JsVar *str, size_t startIdx) {
  JsvStringIterator sit;
  jsvStringIteratorNew(&sit, str, startIdx);
  while (jsvStringIteratorHasChar(&sit)) {
    jsvStringIteratorAppend(it, jsvStringIteratorGetChar(&sit));
    jsvStringIteratorNext(&sit);
  }
  jsvStringIteratorFree(&sit);
}
Ejemplo n.º 14
0
void jslSeekToP(JslCharPos *seekToChar) {
  if (lex->it.var) jsvLockAgain(lex->it.var); // see jslGetNextCh
  jsvStringIteratorFree(&lex->it);
  lex->it = jsvStringIteratorClone(&seekToChar->it);
  jsvUnLock(lex->it.var); // see jslGetNextCh
  lex->currCh = seekToChar->currCh;
  lex->tokenStart.it.var = 0;
  lex->tokenStart.currCh = 0;
  jslGetNextToken();
}
Ejemplo n.º 15
0
void jsfGetJSONWhitespace(JsVar *var, JsVar *result, JSONFlags flags, const char *whitespace) {
  assert(jsvIsString(result));
  JsvStringIterator it;
  jsvStringIteratorNew(&it, result, 0);
  jsvStringIteratorGotoEnd(&it);

  jsfGetJSONWithCallback(var, flags, whitespace, (vcbprintf_callback)&jsvStringIteratorPrintfCallback, &it);

  jsvStringIteratorFree(&it);
}
Ejemplo n.º 16
0
void jslKill(JsLex *lex) {
  lex->tk = LEX_EOF; // safety ;)
  jsvStringIteratorFree(&lex->it);
  if (lex->tokenValue) {
    jsvUnLock(lex->tokenValue);
    lex->tokenValue = 0;
  }
  jsvUnLock(lex->sourceVar);
  lex->tokenStart.it.var = 0;
  lex->tokenStart.currCh = 0;
}
Ejemplo n.º 17
0
void jsfGetEscapedString(JsVar *var, vcbprintf_callback user_callback, void *user_data) {
  user_callback("\"",user_data);
  JsvStringIterator it;
  jsvStringIteratorNew(&it, var, 0);
  while (jsvStringIteratorHasChar(&it)) {
    char ch = jsvStringIteratorGetChar(&it);
    user_callback(escapeCharacter(ch), user_data);
    jsvStringIteratorNext(&it);
  }
  jsvStringIteratorFree(&it);
  user_callback("\"",user_data);
}
Ejemplo n.º 18
0
void jslKill() {
  lex->tk = LEX_EOF; // safety ;)
  if (lex->it.var) jsvLockAgain(lex->it.var); // see jslGetNextCh
  jsvStringIteratorFree(&lex->it);
  if (lex->tokenValue) {
    jsvUnLock(lex->tokenValue);
    lex->tokenValue = 0;
  }
  jsvUnLock(lex->sourceVar);
  lex->tokenStart.it.var = 0;
  lex->tokenStart.currCh = 0;
}
Ejemplo n.º 19
0
void jslPrintTokenLineMarker(vcbprintf_callback user_callback, void *user_data, size_t tokenPos, char *prefix) {
  size_t line = 1,col = 1;
  jsvGetLineAndCol(lex->sourceVar, tokenPos, &line, &col);
  size_t startOfLine = jsvGetIndexFromLineAndCol(lex->sourceVar, line, 1);
  size_t lineLength = jsvGetCharsOnLine(lex->sourceVar, line);
  size_t prefixLength = 0;

  if (prefix) {
    user_callback(prefix, user_data);
    prefixLength = strlen(prefix);
  }

  if (lineLength>60 && tokenPos-startOfLine>30) {
    cbprintf(user_callback, user_data, "...");
    size_t skipChars = tokenPos-30 - startOfLine;
    startOfLine += 3+skipChars;
    if (skipChars<=col)
      col -= skipChars;
    else
      col = 0;
    lineLength -= skipChars;
  }

  // print the string until the end of the line, or 60 chars (whichever is less)
  int chars = 0;
  JsvStringIterator it;
  jsvStringIteratorNew(&it, lex->sourceVar, startOfLine);
  unsigned char lastch = 0;
  while (jsvStringIteratorHasChar(&it) && chars<60) {
    unsigned char ch = (unsigned char)jsvStringIteratorGetChar(&it);
    if (ch == '\n') break;
    if (jslNeedSpaceBetween(lastch, ch)) {
      col++;
      user_callback(" ", user_data);
    }
    char buf[32];
    jslFunctionCharAsString(ch, buf, sizeof(buf));
    size_t len = strlen(buf);
    col += len-1;
    user_callback(buf, user_data);
    chars++;
    lastch = ch;
    jsvStringIteratorNext(&it);
  }
  jsvStringIteratorFree(&it);

  if (lineLength > 60)
    user_callback("...", user_data);
  user_callback("\n", user_data);
  col += prefixLength;
  while (col-- > 1) user_callback(" ", user_data);
  user_callback("^\n", user_data);
}
Ejemplo n.º 20
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "toUpperCase",
  "generate_full" : "jswrap_string_toUpperLowerCase(parent, true)",
  "params" : [

  ],
  "return" : ["JsVar","The uppercase version of this string"]
}*/
JsVar *jswrap_string_toUpperLowerCase(JsVar *parent, bool upper) {
  JsVar *res = jsvNewFromEmptyString();
  if (!res) return 0; // out of memory
  JsVar *parentStr = jsvAsString(parent);

  JsvStringIterator itsrc, itdst;
  jsvStringIteratorNew(&itsrc, parentStr, 0);
  jsvStringIteratorNew(&itdst, res, 0);

  while (jsvStringIteratorHasChar(&itsrc)) {
    char ch = jsvStringIteratorGetChar(&itsrc);
    ch = upper ? jsvStringCharToUpper(ch) : jsvStringCharToLower(ch);
    jsvStringIteratorAppend(&itdst, ch);
    jsvStringIteratorNext(&itsrc);
  }

  jsvStringIteratorFree(&itsrc);
  jsvStringIteratorFree(&itdst);
  jsvUnLock(parentStr);

  return res;
}
Ejemplo n.º 21
0
/*JSON{  "type" : "method", "class" : "File", "name" : "read",
         "generate" : "jswrap_file_read",
         "description" : [ "Read data in a file in byte size chunks"],
         "params" : [ ["length", "int32", "is an integer specifying the number of bytes to read."] ],
         "return" : [ "JsVar", "A string containing the characters that were read" ]
}*/
JsVar *jswrap_file_read(JsVar* parent, int length) {
  JsVar *buffer = 0;
  JsvStringIterator it;
  FRESULT res = 0;
  size_t bytesRead = 0;
  if (jsfsInit()) {
    JsFile file;
    if (fileGetFromVar(&file, parent)) {
      if(file.data.mode == FM_READ || file.data.mode == FM_READ_WRITE) {
        char buf[32];
        size_t actual = 0;

        while (bytesRead < (size_t)length) {
          size_t requested = (size_t)length - bytesRead;
          if (requested > sizeof( buf ))
            requested = sizeof( buf );
          actual = 0;
    #ifndef LINUX
          res = f_read(&file.data.handle, buf, requested, &actual);
          if(res) break;
    #else
          actual = fread(buf, 1, requested, file.data.handle);
    #endif
          if (actual>0) {
            if (!buffer) {
              buffer = jsvNewFromEmptyString();
              if (!buffer) return 0; // out of memory
              jsvStringIteratorNew(&it, buffer, 0);
            }
            size_t i;
            for (i=0;i<actual;i++)
              jsvStringIteratorAppend(&it, buf[i]);
          }
          bytesRead += actual;
          if(actual != requested) break;
        }
        fileSetVar(&file);
      }
    }
  }
  if (res) jsfsReportError("Unable to read file", res);

  if (buffer)
    jsvStringIteratorFree(&it);

  // automatically close this file if we're at the end of it
  if (bytesRead!=(size_t)length)
    jswrap_file_close(parent);

  return buffer;
}
Ejemplo n.º 22
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "charAt",
  "generate" : "jswrap_string_charAt",
  "params" : [
    ["pos","int","The character number in the string. Negative values return characters from end of string (-1 = last char)"]
  ],
  "return" : ["JsVar","The character in the string"]
}
Return a single character at the given position in the String.
*/
JsVar *jswrap_string_charAt(JsVar *parent, JsVarInt idx) {
  // We do this so we can handle '/0' in a string
  JsVar *r = jsvNewFromEmptyString();
  if (r && jsvIsString(parent) && idx>=0) {
    JsvStringIterator it;
    jsvStringIteratorNew(&it, parent, (size_t)idx);
    if (jsvStringIteratorHasChar(&it)) {
      char ch = jsvStringIteratorGetChar(&it);
      jsvAppendStringBuf(r, &ch, 1);
    }
    jsvStringIteratorFree(&it);
  }
  return r;
}
Ejemplo n.º 23
0
/*JSON{
  "type" : "method",
  "class" : "String",
  "name" : "toUpperCase",
  "generate_full" : "jswrap_string_toUpperLowerCase(parent, true)",
  "params" : [
    
  ],
  "return" : ["JsVar","The uppercase version of this string"]
}*/
JsVar *jswrap_string_toUpperLowerCase(JsVar *parent, bool upper) {
  JsVar *res = jsvNewFromEmptyString();
  if (!res) return 0; // out of memory

  JsvStringIterator itsrc, itdst;
  jsvStringIteratorNew(&itsrc, parent, 0);
  jsvStringIteratorNew(&itdst, res, 0);

  while (jsvStringIteratorHasChar(&itsrc)) {
    char ch = jsvStringIteratorGetChar(&itsrc);
    if (upper) {
      if (ch >= 97 && ch <= 122) ch = (char)(ch - 32);
    } else {
      if (ch >= 65 && ch <= 90) ch = (char)(ch + 32); // A-Z
    }
    jsvStringIteratorAppend(&itdst, ch);
    jsvStringIteratorNext(&itsrc);
  }

  jsvStringIteratorFree(&itsrc);
  jsvStringIteratorFree(&itdst);

  return res;
}
Ejemplo n.º 24
0
/// Does this regex have the given flag?
bool jswrap_regexp_hasFlag(JsVar *parent, char flag) {
  JsVar *flags = jsvObjectGetChild(parent, "flags", 0);
  bool has = false;
  if (jsvIsString(flags)) {
    JsvStringIterator it;
    jsvStringIteratorNew(&it, flags, 0);
    while (jsvStringIteratorHasChar(&it)) {
      has |= jsvStringIteratorGetChar(&it)==flag;
      jsvStringIteratorNext(&it);
    }
    jsvStringIteratorFree(&it);
  }
  jsvUnLock(flags);
  return has;
}
Ejemplo n.º 25
0
void jslPrintTokenLineMarker(vcbprintf_callback user_callback, void *user_data, size_t tokenPos, char *prefix) {
  size_t line = 1,col = 1;
  jsvGetLineAndCol(lex->sourceVar, tokenPos, &line, &col);
  size_t startOfLine = jsvGetIndexFromLineAndCol(lex->sourceVar, line, 1);
  size_t lineLength = jsvGetCharsOnLine(lex->sourceVar, line);
  size_t prefixLength = 0;

  if (prefix) {
    user_callback(prefix, user_data);
    prefixLength = strlen(prefix);
  }

  if (lineLength>60 && tokenPos-startOfLine>30) {
    cbprintf(user_callback, user_data, "...");
    size_t skipChars = tokenPos-30 - startOfLine;
    startOfLine += 3+skipChars;
    col -= skipChars;
    lineLength -= skipChars;
  }

  // print the string until the end of the line, or 60 chars (whichever is lesS)
  int chars = 0;
  JsvStringIterator it;
  jsvStringIteratorNew(&it, lex->sourceVar, startOfLine);
  while (jsvStringIteratorHasChar(&it) && chars<60) {
    char ch = jsvStringIteratorGetChar(&it);
    if (ch == '\n') break;
    char buf[2];
    buf[0] = ch;
    buf[1] = 0;
    user_callback(buf, user_data);
    chars++;
    jsvStringIteratorNext(&it);
  }
  jsvStringIteratorFree(&it);

  if (lineLength > 60)
    user_callback("...", user_data);
  user_callback("\n", user_data);
  col += prefixLength;
  while (col-- > 1) user_callback(" ", user_data);
  user_callback("^\n", user_data);
}
Ejemplo n.º 26
0
// No match found, so search to end of regex to see if there's an '|'
static JsVar *nomatchfound(char *regexp, matchInfo info) {
  if (!jspCheckStackPosition()) return 0;
  // TODO: | inside a group?
  while (*regexp && *regexp!='|') {
    if (*regexp=='\\') {
      regexp++; // end of regex after escape char!
      if (!*regexp) return 0;
    }
    regexp++;
  }
  if (*regexp != '|') return 0;
  regexp++;

  JsvStringIterator txtIt;
  jsvStringIteratorNew(&txtIt,  info.sourceStr, info.startIndex);
  JsVar *rmatch = matchhere(regexp, &txtIt, info);
  jsvStringIteratorFree(&txtIt);
  return rmatch;
}
Ejemplo n.º 27
0
static void jslLexRegex() {
  lex->tokenValue = jsvNewFromEmptyString();
  if (!lex->tokenValue) {
    lex->tk = LEX_EOF;
    return;
  }
  JsvStringIterator it;
  jsvStringIteratorNew(&it, lex->tokenValue, 0);
  jsvStringIteratorAppend(&it, '/');
  // strings...
  jslGetNextCh();
  while (lex->currCh && lex->currCh!='/') {
    if (lex->currCh == '\\') {
      jsvStringIteratorAppend(&it, lex->currCh);
      jslGetNextCh();
    } else if (lex->currCh=='\n') {
      /* Was a newline - this is now allowed
       * unless we're a template string */
      break;
    }
    jsvStringIteratorAppend(&it, lex->currCh);
    jslGetNextCh();
  }
  lex->tk = LEX_REGEX;
  if (lex->currCh!='/') {
    lex->tk++; // +1 gets you to 'unfinished X'
  } else {
    jsvStringIteratorAppend(&it, '/');
    jslGetNextCh();
    // regex modifiers
    while (lex->currCh=='g' ||
        lex->currCh=='i' ||
        lex->currCh=='m' ||
        lex->currCh=='y' ||
        lex->currCh=='u') {
      jslTokenAppendChar(lex->currCh);
      jsvStringIteratorAppend(&it, lex->currCh);
      jslGetNextCh();
    }
  }
  jsvStringIteratorFree(&it);
}
Ejemplo n.º 28
0
/** Iterate over the contents of var, calling callback for each. Contents may be:
 *   * numeric -> output
 *   * a string -> output each character
 *   * array/arraybuffer -> call itself on each element
 *   * object -> call itself object.count times, on object.data
 */
bool jsvIterateCallback(JsVar *data, void (*callback)(int item, void *callbackData), void *callbackData) {
  bool ok = true;
  if (jsvIsNumeric(data)) {
    callback((int)jsvGetInteger(data), callbackData);
  } else if (jsvIsObject(data)) {
    JsVar *countVar = jsvObjectGetChild(data, "count", 0);
    JsVar *dataVar = jsvObjectGetChild(data, "data", 0);
    if (countVar && dataVar && jsvIsNumeric(countVar)) {
      int n = (int)jsvGetInteger(countVar);
      while (ok && n-- > 0) {
        ok = jsvIterateCallback(dataVar, callback, callbackData);
      }
    } else {
      jsWarn("If specifying an object, it must be of the form {data : ..., count : N}");
    }
    jsvUnLock(countVar);
    jsvUnLock(dataVar);
  } else if (jsvIsString(data)) {
    JsvStringIterator it;
    jsvStringIteratorNew(&it, data, 0);
    while (jsvStringIteratorHasChar(&it) && ok) {
      char ch = jsvStringIteratorGetChar(&it);
      callback(ch, callbackData);
      jsvStringIteratorNext(&it);
    }
    jsvStringIteratorFree(&it);
  } else if (jsvIsIterable(data)) {
    JsvIterator it;
    jsvIteratorNew(&it, data);
    while (jsvIteratorHasElement(&it) && ok) {
      JsVar *el = jsvIteratorGetValue(&it);
      ok = jsvIterateCallback(el, callback, callbackData);
      jsvUnLock(el);
      jsvIteratorNext(&it);
    }
    jsvIteratorFree(&it);
  } else {
    jsWarn("Expecting a number or something iterable, got %t", data);
    ok = false;
  }
  return ok;
}
Ejemplo n.º 29
0
/*JSON{ "type":"function", "name" : "isNaN",
         "description" : "Whether the x is NaN (Not a Number) or not",
         "generate" : "jswrap_isNaN",
         "params" :  [ [ "x", "JsVar", ""] ],
         "return" : ["bool", "True is the value is NaN, false if not."]
}*/
bool jswrap_isNaN(JsVar *v) {
  if (jsvIsUndefined(v) ||
      jsvIsObject(v) ||
      (jsvIsFloat(v) && isnan(jsvGetFloat(v)))) return true;
  if (jsvIsString(v)) {
    // this is where is can get a bit crazy
    bool allWhiteSpace = true;
    JsvStringIterator it;
    jsvStringIteratorNew(&it,v,0);
    while (jsvStringIteratorHasChar(&it)) {
      if (!isWhitespace(jsvStringIteratorGetChar(&it))) {
        allWhiteSpace = false;
        break;
      }
      jsvStringIteratorNext(&it);
    }
    jsvStringIteratorFree(&it);
    if (allWhiteSpace) return false;
    return isnan(jsvGetFloat(v));
  }
  return false;
}
Ejemplo n.º 30
0
JsVar *jslNewFromLexer(struct JsLex *lex, JslCharPos *charFrom, size_t charTo) {
  // Create a var
  JsVar *var = jsvNewFromEmptyString();
  if (!var) { // out of memory
    return 0;
  }

  //jsvAppendStringVar(var, lex->sourceVar, charFrom->it->index, (int)(charTo-charFrom));
  size_t maxLength = charTo - jsvStringIteratorGetIndex(&charFrom->it);
  JsVar *block = jsvLockAgain(var);
  block->varData.str[0] = charFrom->currCh;
  size_t blockChars = 1;

  // now start appending
  JsvStringIterator it = jsvStringIteratorClone(&charFrom->it);
  while (jsvStringIteratorHasChar(&it) && (maxLength-->0)) {
    char ch = jsvStringIteratorGetChar(&it);
    if (blockChars >= jsvGetMaxCharactersInVar(block)) {
      jsvSetCharactersInVar(block, blockChars);
      JsVar *next = jsvNewWithFlags(JSV_STRING_EXT);
      if (!next) break; // out of memory
      // we don't ref, because  StringExts are never reffed as they only have one owner (and ALWAYS have an owner)
      block->lastChild = jsvGetRef(next);
      jsvUnLock(block);
      block = next;
      blockChars=0; // it's new, so empty
    }
    block->varData.str[blockChars++] = ch;
    jsvStringIteratorNext(&it);
  }
  jsvStringIteratorFree(&it);
  jsvSetCharactersInVar(block, blockChars);
  jsvUnLock(block);

  return var;
}