GLECSVDataStatus GLECSVData::readCellString(GLEBYTE quote) { unsigned int cellSize = 1; unsigned int cellPos = lastCharPos(); initWritePos(); while (true) { GLEBYTE ch = readChar(); writeChar(ch); cellSize++; if (ch == 0) { m_error.errorCode = GLECSVErrorUnterminatedString; m_error.errorLine = m_lines; m_error.errorColumn = getUTF8Column(cellPos); createErrorString("unterminated string"); return GLECSVDataStatusEOF; } else if (isEol(ch)) { m_error.errorCode = GLECSVErrorUnterminatedString; m_error.errorLine = m_lines; m_error.errorColumn = getUTF8Column(cellPos); createErrorString("unterminated string"); return readNewline(ch); } else if (ch == quote) { GLEBYTE ch = readChar(); if (ch != quote) { writeChar(ch); createCell(cellSize, cellPos); return skipSpacesAndFirstDelim(ch); } } } return GLECSVDataStatusOK; }
GLECSVDataStatus GLECSVData::skipTillEol() { while (true) { GLEBYTE ch = readChar(); if (ch == 0) { return GLECSVDataStatusEOF; } if (isEol(ch)) { return readNewline(ch); } } }
extern void read_string(char **pstr, int *plen) { s_zero(pstr); skipblanks(); if (ch == '\"') { /* String quoted in "" */ nextch(); while (1) { if (isEol(ch)) { compile_error(-/*Missing \"*/69); LONGJMP(file.jbSkipLine); } if (ch == '\"') break; s_catchar(pstr, plen, ch); nextch(); } } else { /* Unquoted string */ while (1) { if (isEol(ch) || isComm(ch)) { if (!*pstr || !(*pstr)[0]) { compile_error(-/*Expecting string field*/121); LONGJMP(file.jbSkipLine); } return; } if (isBlank(ch)) break; s_catchar(pstr, plen, ch); nextch(); } } nextch(); }
/* read word */ static void get_word(void) { s_zero(&buffer); skipblanks(); while (!isBlank(ch) && !isEol(ch)) { s_catchar(&buffer, &buf_len, (char)ch); nextch(); } if (!buffer) s_catchar(&buffer, &buf_len, '\0'); #if 0 printf("get_word() got “%s”\n", buffer); #endif }
Token Lexer::nextToken() { if (atEof_) { return Token(TokenType::END_OF_INPUT, ""); } if (std::isdigit(next_)) { return parseNumber(); } else if (isIdentifierStart(next_)) { return parseIdentifier(); } else if (isEol(next_)) { return parseNewLine(); } else { return parseOperator(); } }
GLECSVDataStatus GLECSVData::readNewline(GLEBYTE prevCh) { m_lines++; m_nextLine = true; GLEBYTE ch = readChar(); if (ch == 0) { m_firstColumn = m_pos; return GLECSVDataStatusEOF; } if (isEol(ch) && (ch != prevCh)) { // Found, e.g., CR followed by LF (Windows encoding of new line) m_firstColumn = m_pos; return GLECSVDataStatusEOL; } // Found just CR or just LF (Unix / Mac encoding of new line) goBack(); m_firstColumn = m_pos; return GLECSVDataStatusEOL; }
GLECSVDataStatus GLECSVData::skipSpacesAndFirstDelim(GLEBYTE ch) { while (true) { if (!isSpace(ch)) { if (ch == 0) { return GLECSVDataStatusEOF; } else if (isEol(ch)) { return readNewline(ch); } else if (isDelim(ch)) { m_lastDelimWasSpace = isSpace(ch); return GLECSVDataStatusOK; } else { goBack(); return GLECSVDataStatusOK; } } ch = readChar(); } return GLECSVDataStatusOK; }
GLECSVDataStatus GLECSVData::readCell() { GLEBYTE ch = readSignificantChar(); if (ch == '"' || ch == '\'') { return readCellString(ch); } unsigned int cellCount = 0; unsigned int cellSize = 0; unsigned int cellPos = lastCharPos(); while (true) { if (ch == 0) { if (isSizeCheckOKEndOfLine(cellSize)) { createCell(cellSize, cellPos); } return GLECSVDataStatusEOF; } else if (isEol(ch)) { if (isSizeCheckOKEndOfLine(cellSize)) { createCell(cellSize, cellPos); } return readNewline(ch); } else if (isDelim(ch)) { m_lastDelimWasSpace = isSpace(ch); if (isSizeCheckOKAtDelim(ch, cellSize)) { createCell(cellSize, cellPos); } return skipSpacesAndFirstDelim(ch); } else if (isComment(ch)) { if (isSizeCheckOKEndOfLine(cellSize)) { createCell(cellSize, cellPos); } return skipTillEol(); } cellCount++; if (!isSpace(ch)) { cellSize = cellCount; } ch = readChar(); } return GLECSVDataStatusOK; }
void Lexer::skipSpaces() { while (!atEof_ && !isEol(next_) && std::isspace(next_)) { advance(); } }
static void cmd_fix(void) { prefix *fix_name; node *stn = NULL; static node *stnOmitAlready = NULL; real x, y, z; int nx, ny, nz; filepos fp; fix_name = read_prefix(PFX_STATION|PFX_ALLOW_ROOT); fix_name->sflags |= BIT(SFLAGS_FIXED); get_pos(&fp); get_token(); if (strcmp(ucbuffer, "REFERENCE") == 0) { /* suppress "unused fixed point" warnings for this station */ fix_name->sflags |= BIT(SFLAGS_USED); } else { if (*ucbuffer) set_pos(&fp); } x = read_numeric(fTrue, &nx); if (x == HUGE_REAL) { /* If the end of the line isn't blank, read a number after all to * get a more helpful error message */ if (!isEol(ch) && !isComm(ch)) x = read_numeric(fFalse, &nx); } if (x == HUGE_REAL) { if (stnOmitAlready) { if (fix_name != stnOmitAlready->name) { compile_error_skip(/*More than one FIX command with no coordinates*/56); } else { compile_warning(/*Same station fixed twice with no coordinates*/61); } return; } stn = StnFromPfx(fix_name); compile_warning(/*FIX command with no coordinates - fixing at (0,0,0)*/54); x = y = z = (real)0.0; stnOmitAlready = stn; } else { real sdx; y = read_numeric(fFalse, &ny); z = read_numeric(fFalse, &nz); sdx = read_numeric(fTrue, NULL); if (sdx != HUGE_REAL) { real sdy, sdz; real cxy = 0, cyz = 0, czx = 0; sdy = read_numeric(fTrue, NULL); if (sdy == HUGE_REAL) { /* only one variance given */ sdy = sdz = sdx; } else { sdz = read_numeric(fTrue, NULL); if (sdz == HUGE_REAL) { /* two variances given - horizontal & vertical */ sdz = sdy; sdy = sdx; } else { cxy = read_numeric(fTrue, NULL); if (cxy != HUGE_REAL) { /* covariances given */ cyz = read_numeric(fFalse, NULL); czx = read_numeric(fFalse, NULL); } else { cxy = 0; } } } stn = StnFromPfx(fix_name); if (!fixed(stn)) { node *fixpt = osnew(node); prefix *name; name = osnew(prefix); name->pos = osnew(pos); name->ident = NULL; name->shape = 0; fixpt->name = name; name->stn = fixpt; name->up = NULL; if (TSTBIT(pcs->infer, INFER_EXPORTS)) { name->min_export = USHRT_MAX; } else { name->min_export = 0; } name->max_export = 0; name->sflags = 0; add_stn_to_list(&stnlist, fixpt); POS(fixpt, 0) = x; POS(fixpt, 1) = y; POS(fixpt, 2) = z; fix(fixpt); fixpt->leg[0] = fixpt->leg[1] = fixpt->leg[2] = NULL; addfakeleg(fixpt, stn, 0, 0, 0, sdx * sdx, sdy * sdy, sdz * sdz #ifndef NO_COVARIANCES , cxy, cyz, czx #endif ); } return; } stn = StnFromPfx(fix_name); } if (!fixed(stn)) { POS(stn, 0) = x; POS(stn, 1) = y; POS(stn, 2) = z; fix(stn); return; } if (x != POS(stn, 0) || y != POS(stn, 1) || z != POS(stn, 2)) { compile_error(/*Station already fixed or equated to a fixed point*/46); return; } compile_warning(/*Station already fixed at the same coordinates*/55); }
static void cmd_set(void) { static sztok chartab[] = { {"BLANK", SPECIAL_BLANK }, /*FIXME {"CLOSE", SPECIAL_CLOSE }, */ {"COMMENT", SPECIAL_COMMENT }, {"DECIMAL", SPECIAL_DECIMAL }, {"EOL", SPECIAL_EOL }, /* EOL won't work well */ {"KEYWORD", SPECIAL_KEYWORD }, {"MINUS", SPECIAL_MINUS }, {"NAMES", SPECIAL_NAMES }, {"OMIT", SPECIAL_OMIT }, /*FIXME {"OPEN", SPECIAL_OPEN }, */ {"PLUS", SPECIAL_PLUS }, #ifndef NO_DEPRECATED {"ROOT", SPECIAL_ROOT }, #endif {"SEPARATOR", SPECIAL_SEPARATOR }, {NULL, SPECIAL_UNKNOWN } }; int mask; int i; get_token(); mask = match_tok(chartab, TABSIZE(chartab)); if (mask == SPECIAL_UNKNOWN) { file.lpos += strlen(buffer); compile_error_skip(-/*Unknown character class “%s”*/42, buffer); return; } #ifndef NO_DEPRECATED if (mask == SPECIAL_ROOT) { if (root_depr_count < 5) { file.lpos += strlen(buffer); compile_warning(-/*ROOT is deprecated*/25); if (++root_depr_count == 5) compile_warning(/*Further uses of this deprecated feature will not be reported*/95); } } #endif /* if we're currently using an inherited translation table, allocate a new * table, and copy old one into it */ if (pcs->next && pcs->next->Translate == pcs->Translate) { short *p; p = ((short*)osmalloc(ossizeof(short) * 257)) + 1; memcpy(p - 1, pcs->Translate - 1, sizeof(short) * 257); pcs->Translate = p; } skipblanks(); /* clear this flag for all non-alphanums */ for (i = 0; i < 256; i++) if (!isalnum(i)) pcs->Translate[i] &= ~mask; /* now set this flag for all specified chars */ while (!isEol(ch)) { if (!isalnum(ch)) { pcs->Translate[ch] |= mask; } else if (tolower(ch) == 'x') { int hex; filepos fp; get_pos(&fp); nextch(); if (!isxdigit(ch)) { set_pos(&fp); break; } hex = isdigit(ch) ? ch - '0' : tolower(ch) - 'a'; nextch(); if (!isxdigit(ch)) { set_pos(&fp); break; } hex = hex << 4 | (isdigit(ch) ? ch - '0' : tolower(ch) - 'a'); pcs->Translate[hex] |= mask; } else { break; } nextch(); } }
/* if prefix is omitted: if PFX_OPT set return NULL, otherwise use longjmp */ extern prefix * read_prefix(unsigned pfx_flags) { bool f_optional = !!(pfx_flags & PFX_OPT); bool fSurvey = !!(pfx_flags & PFX_SURVEY); bool fSuspectTypo = !!(pfx_flags & PFX_SUSPECT_TYPO); prefix *back_ptr, *ptr; char *name; size_t name_len = 32; size_t i; bool fNew; bool fImplicitPrefix = fTrue; int depth = -1; filepos fp_firstsep; skipblanks(); #ifndef NO_DEPRECATED if (isRoot(ch)) { if (!(pfx_flags & PFX_ALLOW_ROOT)) { compile_diagnostic(DIAG_ERR|DIAG_COL, /*ROOT is deprecated*/25); LONGJMP(file.jbSkipLine); } if (root_depr_count < 5) { compile_diagnostic(DIAG_WARN|DIAG_COL, /*ROOT is deprecated*/25); if (++root_depr_count == 5) compile_diagnostic(DIAG_WARN, /*Further uses of this deprecated feature will not be reported*/95); } nextch(); ptr = root; if (!isNames(ch)) { if (!isSep(ch)) return ptr; /* Allow optional SEPARATOR after ROOT */ get_pos(&fp_firstsep); nextch(); } fImplicitPrefix = fFalse; #else if (0) { #endif } else { if ((pfx_flags & PFX_ANON) && (isSep(ch) || (pcs->dash_for_anon_wall_station && ch == '-'))) { int first_ch = ch; filepos here; get_pos(&here); nextch(); if (isBlank(ch) || isEol(ch)) { if (!isSep(first_ch)) goto anon_wall_station; /* A single separator alone ('.' by default) is an anonymous * station which is on a point inside the passage and implies * the leg to it is a splay. */ if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) { set_pos(&here); compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3); LONGJMP(file.jbSkipLine); } pcs->flags |= BIT(FLAGS_ANON_ONE_END) | BIT(FLAGS_IMPLICIT_SPLAY); return new_anon_station(); } if (isSep(first_ch) && ch == first_ch) { nextch(); if (isBlank(ch) || isEol(ch)) { /* A double separator ('..' by default) is an anonymous station * which is on the wall and implies the leg to it is a splay. */ prefix * pfx; anon_wall_station: if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) { set_pos(&here); compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3); LONGJMP(file.jbSkipLine); } pcs->flags |= BIT(FLAGS_ANON_ONE_END) | BIT(FLAGS_IMPLICIT_SPLAY); pfx = new_anon_station(); pfx->sflags |= BIT(SFLAGS_WALL); return pfx; } if (ch == first_ch) { nextch(); if (isBlank(ch) || isEol(ch)) { /* A triple separator ('...' by default) is an anonymous * station, but otherwise not handled specially (e.g. for * a single leg down an unexplored side passage to a station * which isn't refindable). */ if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) { set_pos(&here); compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3); LONGJMP(file.jbSkipLine); } pcs->flags |= BIT(FLAGS_ANON_ONE_END); return new_anon_station(); } } } set_pos(&here); } ptr = pcs->Prefix; } i = 0; name = NULL; do { fNew = fFalse; if (name == NULL) { /* Need a new name buffer */ name = osmalloc(name_len); } /* i==0 iff this is the first pass */ if (i) { i = 0; nextch(); } while (isNames(ch)) { if (i < pcs->Truncate) { /* truncate name */ name[i++] = (pcs->Case == LOWER ? tolower(ch) : (pcs->Case == OFF ? ch : toupper(ch))); if (i >= name_len) { name_len = name_len + name_len; name = osrealloc(name, name_len); } } nextch(); } if (isSep(ch)) { fImplicitPrefix = fFalse; get_pos(&fp_firstsep); } if (i == 0) { osfree(name); if (!f_optional) { if (isEol(ch)) { if (fSurvey) { compile_diagnostic(DIAG_ERR|DIAG_COL, /*Expecting survey name*/89); } else { compile_diagnostic(DIAG_ERR|DIAG_COL, /*Expecting station name*/28); } } else { /* TRANSLATORS: Here "station" is a survey station, not a train station. */ compile_diagnostic(DIAG_ERR|DIAG_COL, /*Character “%c” not allowed in station name (use *SET NAMES to set allowed characters)*/7, ch); } LONGJMP(file.jbSkipLine); } return (prefix *)NULL; } name[i++] = '\0'; back_ptr = ptr; ptr = ptr->down; if (ptr == NULL) { /* Special case first time around at each level */ name = osrealloc(name, i); ptr = osnew(prefix); ptr->ident = name; name = NULL; ptr->right = ptr->down = NULL; ptr->pos = NULL; ptr->shape = 0; ptr->stn = NULL; ptr->up = back_ptr; ptr->filename = file.filename; ptr->line = file.line; ptr->min_export = ptr->max_export = 0; ptr->sflags = BIT(SFLAGS_SURVEY); if (fSuspectTypo && !fImplicitPrefix) ptr->sflags |= BIT(SFLAGS_SUSPECTTYPO); back_ptr->down = ptr; fNew = fTrue; } else { /* Use caching to speed up adding an increasing sequence to a * large survey */ static prefix *cached_survey = NULL, *cached_station = NULL; prefix *ptrPrev = NULL; int cmp = 1; /* result of strcmp ( -ve for <, 0 for =, +ve for > ) */ if (cached_survey == back_ptr) { cmp = strcmp(cached_station->ident, name); if (cmp <= 0) ptr = cached_station; } while (ptr && (cmp = strcmp(ptr->ident, name))<0) { ptrPrev = ptr; ptr = ptr->right; } if (cmp) { /* ie we got to one that was higher, or the end */ prefix *newptr; name = osrealloc(name, i); newptr = osnew(prefix); newptr->ident = name; name = NULL; if (ptrPrev == NULL) back_ptr->down = newptr; else ptrPrev->right = newptr; newptr->right = ptr; newptr->down = NULL; newptr->pos = NULL; newptr->shape = 0; newptr->stn = NULL; newptr->up = back_ptr; newptr->filename = file.filename; newptr->line = file.line; newptr->min_export = newptr->max_export = 0; newptr->sflags = BIT(SFLAGS_SURVEY); if (fSuspectTypo && !fImplicitPrefix) newptr->sflags |= BIT(SFLAGS_SUSPECTTYPO); ptr = newptr; fNew = fTrue; } cached_survey = back_ptr; cached_station = ptr; } depth++; f_optional = fFalse; /* disallow after first level */ if (isSep(ch)) get_pos(&fp_firstsep); } while (isSep(ch)); if (name) osfree(name); /* don't warn about a station that is referred to twice */ if (!fNew) ptr->sflags &= ~BIT(SFLAGS_SUSPECTTYPO); if (fNew) { /* fNew means SFLAGS_SURVEY is currently set */ SVX_ASSERT(TSTBIT(ptr->sflags, SFLAGS_SURVEY)); if (!fSurvey) { ptr->sflags &= ~BIT(SFLAGS_SURVEY); if (TSTBIT(pcs->infer, INFER_EXPORTS)) ptr->min_export = USHRT_MAX; } } else { /* check that the same name isn't being used for a survey and station */ if (fSurvey ^ TSTBIT(ptr->sflags, SFLAGS_SURVEY)) { /* TRANSLATORS: Here "station" is a survey station, not a train station. * * Here "survey" is a "cave map" rather than list of questions - it should be * translated to the terminology that cavers using the language would use. */ compile_diagnostic(DIAG_ERR, /*“%s” can’t be both a station and a survey*/27, sprint_prefix(ptr)); } if (!fSurvey && TSTBIT(pcs->infer, INFER_EXPORTS)) ptr->min_export = USHRT_MAX; } /* check the export level */ #if 0 printf("R min %d max %d depth %d pfx %s\n", ptr->min_export, ptr->max_export, depth, sprint_prefix(ptr)); #endif if (ptr->min_export == 0 || ptr->min_export == USHRT_MAX) { if (depth > ptr->max_export) ptr->max_export = depth; } else if (ptr->max_export < depth) { prefix *survey = ptr; char *s; const char *p; int level; for (level = ptr->max_export + 1; level; level--) { survey = survey->up; SVX_ASSERT(survey); } s = osstrdup(sprint_prefix(survey)); p = sprint_prefix(ptr); if (survey->filename) { compile_diagnostic_pfx(DIAG_ERR, survey, /*Station “%s” not exported from survey “%s”*/26, p, s); } else { compile_diagnostic(DIAG_ERR, /*Station “%s” not exported from survey “%s”*/26, p, s); } osfree(s); #if 0 printf(" *** pfx %s warning not exported enough depth %d " "ptr->max_export %d\n", sprint_prefix(ptr), depth, ptr->max_export); #endif } if (!fImplicitPrefix && (pfx_flags & PFX_WARN_SEPARATOR)) { filepos fp_tmp; get_pos(&fp_tmp); set_pos(&fp_firstsep); compile_diagnostic(DIAG_WARN|DIAG_COL, /*Separator in survey name*/392); set_pos(&fp_tmp); } return ptr; } /* if numeric expr is omitted: if f_optional return HUGE_REAL, else longjmp */ static real read_number(bool f_optional) { bool fPositive, fDigits = fFalse; real n = (real)0.0; filepos fp; int ch_old; get_pos(&fp); ch_old = ch; fPositive = !isMinus(ch); if (isSign(ch)) nextch(); while (isdigit(ch)) { n = n * (real)10.0 + (char)(ch - '0'); nextch(); fDigits = fTrue; } if (isDecimal(ch)) { real mult = (real)1.0; nextch(); while (isdigit(ch)) { mult *= (real).1; n += (char)(ch - '0') * mult; fDigits = fTrue; nextch(); } } /* !'fRead' => !fDigits so fDigits => 'fRead' */ if (fDigits) return (fPositive ? n : -n); /* didn't read a valid number. If it's optional, reset filepos & return */ set_pos(&fp); if (f_optional) { return HUGE_REAL; } if (isOmit(ch_old)) { compile_diagnostic(DIAG_ERR|DIAG_COL, /*Field may not be omitted*/8); } else { compile_diagnostic_token_show(DIAG_ERR, /*Expecting numeric field, found “%s”*/9); } LONGJMP(file.jbSkipLine); return 0.0; /* for brain-fried compilers */ }