bool CPLJSonStreamingParser::StartNewToken(const char*& pStr, size_t& nLength) { char ch = *pStr; if( ch == '{' ) { if( m_aState.size() == m_nMaxDepth ) { return EmitException("Too many nested objects and/or arrays"); } StartObject(); m_aeObjectState.push_back(WAITING_KEY); m_aState.push_back(OBJECT); AdvanceChar(pStr, nLength); } else if( ch == '"' ) { m_aState.push_back(STRING); AdvanceChar(pStr, nLength); } else if( ch == '[' ) { if( m_aState.size() == m_nMaxDepth ) { return EmitException("Too many nested objects and/or arrays"); } StartArray(); m_abFirstElement.push_back(true); m_aState.push_back(ARRAY); AdvanceChar(pStr, nLength); } else if( ch == '-' || ch == '.' || isdigit(ch) ) { m_aState.push_back(NUMBER); } else if( ch == 't' ) { m_aState.push_back(STATE_TRUE); } else if( ch == 'f' ) { m_aState.push_back(STATE_FALSE); } else if( ch == 'n' ) { m_aState.push_back(STATE_NULL); } else { assert( false ); } return true; }
Bool ParseRepeatAttr( TidyDocImpl* doc, const TidyOptionImpl* option ) { Bool status = yes; tmbchar buf[64] = {0}; uint i = 0; TidyConfigImpl* cfg = &doc->config; tchar c = SkipWhite( cfg ); while (i < sizeof(buf)-1 && c != EndOfStream && !IsWhite(c)) { buf[i++] = (tmbchar) c; c = AdvanceChar( cfg ); } buf[i] = '\0'; if ( tmbstrcasecmp(buf, "keep-first") == 0 ) cfg->value[ TidyDuplicateAttrs ].v = TidyKeepFirst; else if ( tmbstrcasecmp(buf, "keep-last") == 0 ) cfg->value[ TidyDuplicateAttrs ].v = TidyKeepLast; else { ReportBadArgument( doc, option->name ); status = no; } return status; }
void CPLJSonStreamingParser::SkipSpace(const char*& pStr, size_t& nLength) { while( nLength > 0 && isspace(*pStr) ) { AdvanceChar(pStr, nLength); } }
Bool ParseCharEnc( TidyDocImpl* doc, const TidyOptionImpl* option ) { tmbchar buf[64] = {0}; uint i = 0; int enc = ASCII; Bool validEncoding = yes; tchar c = SkipWhite( &doc->config ); while ( i < sizeof(buf)-2 && c != EndOfStream && !IsWhite(c) ) { buf[i++] = (tmbchar) ToLower( c ); c = AdvanceChar( &doc->config ); } buf[i] = 0; enc = CharEncodingId( buf ); #ifdef TIDY_WIN32_MLANG_SUPPORT /* limit support to --input-encoding */ if (option->id != TidyInCharEncoding && enc > WIN32MLANG) enc = -1; #endif if ( enc < 0 ) { validEncoding = no; ReportBadArgument( doc, option->name ); } else SetOptionInt( doc, option->id, enc ); if ( validEncoding && option->id == TidyCharEncoding ) AdjustCharEncoding( doc, enc ); return validEncoding; }
/* #508936 - CSS class naming for -clean option */ Bool ParseCSS1Selector( TidyDocImpl* doc, const TidyOptionImpl* option ) { char buf[256] = {0}; uint i = 0; uint c = SkipWhite( &doc->config ); while ( i < sizeof(buf)-2 && c != EndOfStream && !IsWhite(c) ) { buf[i++] = (tmbchar) c; c = AdvanceChar( &doc->config ); } buf[i] = '\0'; if ( i == 0 || !IsCSS1Selector(buf) ) { ReportBadArgument( doc, option->name ); return no; } buf[i++] = '-'; /* Make sure any escaped Unicode is terminated */ buf[i] = 0; /* so valid class names are generated after */ /* Tidy appends last digits. */ SetOptionValue( doc, option->id, buf ); return yes; }
/* cr, lf or crlf */ Bool ParseNewline( TidyDocImpl* doc, const TidyOptionImpl* entry ) { int nl = -1; tmbchar work[ 16 ] = {0}; tmbstr cp = work, end = work + sizeof(work); TidyConfigImpl* cfg = &doc->config; tchar c = SkipWhite( cfg ); while ( c!=EndOfStream && cp < end && !IsWhite(c) && c != '\r' && c != '\n' ) { *cp++ = (tmbchar) c; c = AdvanceChar( cfg ); } *cp = 0; if ( tmbstrcasecmp(work, "lf") == 0 ) nl = TidyLF; else if ( tmbstrcasecmp(work, "crlf") == 0 ) nl = TidyCRLF; else if ( tmbstrcasecmp(work, "cr") == 0 ) nl = TidyCR; if ( nl < TidyLF || nl > TidyCR ) ReportBadArgument( doc, entry->name ); else SetOptionInt( doc, entry->id, nl ); return ( nl >= TidyLF && nl <= TidyCR ); }
Bool ParseString( TidyDocImpl* doc, const TidyOptionImpl* option ) { TidyConfigImpl* cfg = &doc->config; tmbchar buf[8192]; uint i = 0; tchar delim = 0; Bool waswhite = yes; tchar c = SkipWhite( cfg ); if ( c == '"' || c == '\'' ) { delim = c; c = AdvanceChar( cfg ); } while ( i < sizeof(buf)-2 && c != EndOfStream && c != '\r' && c != '\n' ) { if ( delim && c == delim ) break; if ( IsWhite(c) ) { if ( waswhite ) { c = AdvanceChar( cfg ); continue; } c = ' '; } else waswhite = no; buf[i++] = (tmbchar) c; c = AdvanceChar( cfg ); } buf[i] = '\0'; SetOptionValue( doc, option->id, buf ); return yes; }
/* doctype: omit | auto | strict | loose | <fpi> where the fpi is a string similar to "-//ACME//DTD HTML 3.14159//EN" */ Bool ParseDocType( TidyDocImpl* doc, const TidyOptionImpl* option ) { tmbchar buf[ 32 ] = {0}; uint i = 0; Bool status = yes; TidyDoctypeModes dtmode = TidyDoctypeAuto; TidyConfigImpl* cfg = &doc->config; tchar c = SkipWhite( cfg ); /* "-//ACME//DTD HTML 3.14159//EN" or similar */ if ( c == '"' || c == '\'' ) { status = ParseString(doc, option); if (status) SetOptionInt( doc, TidyDoctypeMode, TidyDoctypeUser ); return status; } /* read first word */ while ( i < sizeof(buf)-1 && c != EndOfStream && !IsWhite(c) ) { buf[i++] = (tmbchar) c; c = AdvanceChar( cfg ); } buf[i] = '\0'; if ( tmbstrcasecmp(buf, "auto") == 0 ) dtmode = TidyDoctypeAuto; else if ( tmbstrcasecmp(buf, "omit") == 0 ) dtmode = TidyDoctypeOmit; else if ( tmbstrcasecmp(buf, "strict") == 0 ) dtmode = TidyDoctypeStrict; else if ( tmbstrcasecmp(buf, "loose") == 0 || tmbstrcasecmp(buf, "transitional") == 0 ) dtmode = TidyDoctypeLoose; else { ReportBadArgument( doc, option->name ); status = no; } if ( status ) SetOptionInt( doc, TidyDoctypeMode, dtmode ); return status; }
/* a string excluding whitespace */ Bool ParseName( TidyDocImpl* doc, const TidyOptionImpl* option ) { tmbchar buf[ 1024 ] = {0}; uint i = 0; uint c = SkipWhite( &doc->config ); while ( i < sizeof(buf)-2 && c != EndOfStream && !IsWhite(c) ) { buf[i++] = (tmbchar) c; c = AdvanceChar( &doc->config ); } buf[i] = 0; if ( i == 0 ) ReportBadArgument( doc, option->name ); else SetOptionValue( doc, option->id, buf ); return ( i > 0 ); }
/* unsigned integers */ Bool ParseInt( TidyDocImpl* doc, const TidyOptionImpl* entry ) { ulong number = 0; Bool digits = no; TidyConfigImpl* cfg = &doc->config; tchar c = SkipWhite( cfg ); while ( IsDigit(c) ) { number = c - '0' + (10 * number); digits = yes; c = AdvanceChar( cfg ); } if ( !digits ) ReportBadArgument( doc, entry->name ); else SetOptionInt( doc, entry->id, number ); return digits; }
/* open the file and parse its contents */ int ParseConfigFileEnc( TidyDocImpl* doc, ctmbstr file, ctmbstr charenc ) { uint opterrs = doc->optionErrors; tmbstr fname = (tmbstr) ExpandTilde( file ); TidyConfigImpl* cfg = &doc->config; FILE* fin = fopen( fname, "r" ); int enc = CharEncodingId( charenc ); if ( fin == NULL || enc < 0 ) { FileError( doc, fname, TidyConfig ); return -1; } else { tchar c; cfg->cfgIn = FileInput( doc, fin, enc ); c = FirstChar( cfg ); for ( c = SkipWhite(cfg); c != EndOfStream; c = NextProperty(cfg) ) { uint ix = 0; tmbchar name[ TIDY_MAX_NAME ] = {0}; /* // or # start a comment */ if ( c == '/' || c == '#' ) continue; while ( ix < sizeof(name)-1 && c != '\n' && c != EndOfStream && c != ':' ) { name[ ix++ ] = (tmbchar) c; /* Option names all ASCII */ c = AdvanceChar( cfg ); } if ( c == ':' ) { const TidyOptionImpl* option = lookupOption( name ); c = AdvanceChar( cfg ); if ( option ) option->parser( doc, option ); else { if (NULL != doc->pOptCallback) { TidyConfigImpl* cfg = &doc->config; tmbchar buf[8192]; uint i = 0; tchar delim = 0; Bool waswhite = yes; tchar c = SkipWhite( cfg ); if ( c == '"' || c == '\'' ) { delim = c; c = AdvanceChar( cfg ); } while ( i < sizeof(buf)-2 && c != EndOfStream && c != '\r' && c != '\n' ) { if ( delim && c == delim ) break; if ( IsWhite(c) ) { if ( waswhite ) { c = AdvanceChar( cfg ); continue; } c = ' '; } else waswhite = no; buf[i++] = (tmbchar) c; c = AdvanceChar( cfg ); } buf[i] = '\0'; if (no == (*doc->pOptCallback)( name, buf )) ReportUnknownOption( doc, name ); } else ReportUnknownOption( doc, name ); } } } fclose( fin ); MemFree( (void *)cfg->cfgIn->source.sourceData ); /* fix for bug #810259 */ freeStreamIn( cfg->cfgIn ); cfg->cfgIn = NULL; } if ( fname != (tmbstr) file ) MemFree( fname ); AdjustConfig( doc ); /* any new config errors? If so, return warning status. */ return (doc->optionErrors > opterrs ? 1 : 0); }
/* a space or comma separated list of tag names */ Bool ParseTagNames( TidyDocImpl* doc, const TidyOptionImpl* option ) { TidyConfigImpl* cfg = &doc->config; tmbchar buf[1024]; uint i = 0, nTags = 0; uint c = SkipWhite( cfg ); UserTagType ttyp = tagtype_null; switch ( option->id ) { case TidyInlineTags: ttyp = tagtype_inline; break; case TidyBlockTags: ttyp = tagtype_block; break; case TidyEmptyTags: ttyp = tagtype_empty; break; case TidyPreTags: ttyp = tagtype_pre; break; default: ReportUnknownOption( doc, option->name ); return no; } SetOptionValue( doc, option->id, NULL ); FreeDeclaredTags( doc, ttyp ); cfg->defined_tags |= ttyp; do { if (c == ' ' || c == '\t' || c == ',') { c = AdvanceChar( cfg ); continue; } if ( c == '\r' || c == '\n' ) { uint c2 = AdvanceChar( cfg ); if ( c == '\r' && c2 == '\n' ) c = AdvanceChar( cfg ); else c = c2; if ( !IsWhite(c) ) { buf[i] = 0; UngetChar( c, cfg->cfgIn ); UngetChar( '\n', cfg->cfgIn ); break; } } /* if ( c == '\n' ) { c = AdvanceChar( cfg ); if ( !IsWhite(c) ) { buf[i] = 0; UngetChar( c, cfg->cfgIn ); UngetChar( '\n', cfg->cfgIn ); break; } } */ while ( i < sizeof(buf)-2 && c != EndOfStream && !IsWhite(c) && c != ',' ) { buf[i++] = (tmbchar) c; c = AdvanceChar( cfg ); } buf[i] = '\0'; if (i == 0) /* Skip empty tag definition. Possible when */ continue; /* there is a trailing space on the line. */ /* add tag to dictionary */ DeclareUserTag( doc, option->id, ttyp, buf ); i = 0; ++nTags; } while ( c != EndOfStream ); if ( i > 0 ) DeclareUserTag( doc, option->id, ttyp, buf ); return ( nTags > 0 ); }