/* returns false if unknown option, missing parameter, ** or option doesn't use parameter */ Bool ParseConfigOption( TidyDocImpl* doc, ctmbstr optnam, ctmbstr optval ) { const TidyOptionImpl* option = lookupOption( optnam ); Bool status = ( option != NULL ); if ( !status ) { /* Not a standard tidy option. Check to see if the user application recognizes it */ if (NULL != doc->pOptCallback) status = (*doc->pOptCallback)( optnam, optval ); if (!status) ReportUnknownOption( doc, optnam ); } else status = ParseConfigValue( doc, option->id, optval ); return status; }
bool ReportCommand::ParseOptions(const std::vector<std::string>& args) { bool print_sample_count = false; std::vector<std::string> sort_keys = {"comm", "pid", "tid", "dso", "symbol"}; for (size_t i = 0; i < args.size(); ++i) { if (args[i] == "-b") { use_branch_address_ = true; } else if (args[i] == "--children") { accumulate_callchain_ = true; } else if (args[i] == "-g") { print_callgraph_ = true; accumulate_callchain_ = true; } else if (args[i] == "-i") { if (!NextArgumentOrError(args, &i)) { return false; } record_filename_ = args[i]; } else if (args[i] == "-n") { print_sample_count = true; } else if (args[i] == "--no-demangle") { DsoFactory::SetDemangle(false); } else if (args[i] == "--sort") { if (!NextArgumentOrError(args, &i)) { return false; } sort_keys = android::base::Split(args[i], ","); } else if (args[i] == "--symfs") { if (!NextArgumentOrError(args, &i)) { return false; } if (!DsoFactory::SetSymFsDir(args[i])) { return false; } } else { ReportUnknownOption(args, i); return false; } } if (!accumulate_callchain_) { displayable_items_.push_back( std::unique_ptr<Displayable>(new SelfOverheadItem(*sample_tree_, "Overhead"))); } else { displayable_items_.push_back( std::unique_ptr<Displayable>(new AccumulatedOverheadItem(*sample_tree_))); displayable_items_.push_back(std::unique_ptr<Displayable>(new SelfOverheadItem(*sample_tree_))); } if (print_sample_count) { displayable_items_.push_back(std::unique_ptr<Displayable>(new SampleCountItem)); } for (auto& key : sort_keys) { if (!use_branch_address_ && branch_sort_keys.find(key) != branch_sort_keys.end()) { LOG(ERROR) << "sort key '" << key << "' can only be used with -b option."; return false; } if (key == "pid") { PidItem* item = new PidItem; displayable_items_.push_back(std::unique_ptr<Displayable>(item)); comparable_items_.push_back(item); } else if (key == "tid") { TidItem* item = new TidItem; displayable_items_.push_back(std::unique_ptr<Displayable>(item)); comparable_items_.push_back(item); } else if (key == "comm") { CommItem* item = new CommItem; displayable_items_.push_back(std::unique_ptr<Displayable>(item)); comparable_items_.push_back(item); } else if (key == "dso") { DsoItem* item = new DsoItem; displayable_items_.push_back(std::unique_ptr<Displayable>(item)); comparable_items_.push_back(item); } else if (key == "symbol") { SymbolItem* item = new SymbolItem; displayable_items_.push_back(std::unique_ptr<Displayable>(item)); comparable_items_.push_back(item); } else if (key == "dso_from") { DsoFromItem* item = new DsoFromItem; displayable_items_.push_back(std::unique_ptr<Displayable>(item)); comparable_items_.push_back(item); } else if (key == "dso_to") { DsoToItem* item = new DsoToItem; displayable_items_.push_back(std::unique_ptr<Displayable>(item)); comparable_items_.push_back(item); } else if (key == "symbol_from") { SymbolFromItem* item = new SymbolFromItem; displayable_items_.push_back(std::unique_ptr<Displayable>(item)); comparable_items_.push_back(item); } else if (key == "symbol_to") { SymbolToItem* item = new SymbolToItem; displayable_items_.push_back(std::unique_ptr<Displayable>(item)); comparable_items_.push_back(item); } else { LOG(ERROR) << "Unknown sort key: " << key; return false; } } return true; }
/* 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 ); }