void SkCommandLineFlags::Parse(int argc, char** argv) { // Only allow calling this function once. static bool gOnce; if (gOnce) { SkDebugf("Parse should only be called once at the beginning of main!\n"); SkASSERT(false); return; } gOnce = true; bool helpPrinted = false; // Loop over argv, starting with 1, since the first is just the name of the program. for (int i = 1; i < argc; i++) { if (0 == strcmp("-h", argv[i]) || 0 == strcmp("--help", argv[i])) { // Print help message. SkTDArray<const char*> helpFlags; for (int j = i + 1; j < argc; j++) { if (SkStrStartsWith(argv[j], '-')) { break; } helpFlags.append(1, &argv[j]); } if (0 == helpFlags.count()) { // Only print general help message if help for specific flags is not requested. SkDebugf("%s\n%s\n", argv[0], gUsage.c_str()); } SkDebugf("Flags:\n"); SkFlagInfo* flag = SkCommandLineFlags::gHead; while (flag != NULL) { // If no flags followed --help, print them all bool printFlag = 0 == helpFlags.count(); if (!printFlag) { for (int k = 0; k < helpFlags.count(); k++) { if (flag->name().equals(helpFlags[k]) || flag->shortName().equals(helpFlags[k])) { printFlag = true; helpFlags.remove(k); break; } } } if (printFlag) { print_help_for_flag(flag); } flag = flag->next(); } if (helpFlags.count() > 0) { SkDebugf("Requested help for unrecognized flags:\n"); for (int k = 0; k < helpFlags.count(); k++) { SkDebugf("\t--%s\n", helpFlags[k]); } } helpPrinted = true; } if (!helpPrinted) { bool flagMatched = false; SkFlagInfo* flag = gHead; while (flag != NULL) { if (flag->match(argv[i])) { flagMatched = true; switch (flag->getFlagType()) { case SkFlagInfo::kBool_FlagType: // Can be handled by match, above, but can also be set by the next // string. if (i+1 < argc && !SkStrStartsWith(argv[i+1], '-')) { i++; bool value; if (parse_bool_arg(argv[i], &value)) { flag->setBool(value); } } break; case SkFlagInfo::kString_FlagType: flag->resetStrings(); // Add all arguments until another flag is reached. while (i+1 < argc && !SkStrStartsWith(argv[i+1], '-')) { i++; flag->append(argv[i]); } break; case SkFlagInfo::kInt_FlagType: i++; flag->setInt(atoi(argv[i])); break; case SkFlagInfo::kDouble_FlagType: i++; flag->setDouble(atof(argv[i])); break; default: SkASSERT(!"Invalid flag type"); } break; } flag = flag->next(); } if (!flagMatched) { SkDebugf("Got unknown flag \"%s\". Exiting.\n", argv[i]); exit(-1); } } } // Since all of the flags have been set, release the memory used by each // flag. FLAGS_x can still be used after this. SkFlagInfo* flag = gHead; gHead = NULL; while (flag != NULL) { SkFlagInfo* next = flag->next(); SkDELETE(flag); flag = next; } if (helpPrinted) { exit(0); } }
void SkCommandLineFlags::Parse(int argc, char** argv) { // Only allow calling this function once. static bool gOnce; if (gOnce) { SkDebugf("Parse should only be called once at the beginning of main!\n"); SkASSERT(false); return; } gOnce = true; bool helpPrinted = false; // Loop over argv, starting with 1, since the first is just the name of the program. for (int i = 1; i < argc; i++) { if (0 == strcmp("-h", argv[i]) || 0 == strcmp("--help", argv[i])) { // Print help message. SkTDArray<const char*> helpFlags; for (int j = i + 1; j < argc; j++) { if (SkStrStartsWith(argv[j], '-')) { break; } helpFlags.append(1, &argv[j]); } if (0 == helpFlags.count()) { // Only print general help message if help for specific flags is not requested. SkDebugf("%s\n%s\n", argv[0], gUsage.c_str()); } SkDebugf("Flags:\n"); if (0 == helpFlags.count()) { // If no flags followed --help, print them all SkTDArray<SkFlagInfo*> allFlags; for (SkFlagInfo* flag = SkCommandLineFlags::gHead; flag; flag = flag->next()) { allFlags.push(flag); } SkTQSort(&allFlags[0], &allFlags[allFlags.count() - 1], CompareFlagsByName()); for (int i = 0; i < allFlags.count(); ++i) { print_help_for_flag(allFlags[i]); if (allFlags[i]->extendedHelp().size() > 0) { SkDebugf(" Use '--help %s' for more information.\n", allFlags[i]->name().c_str()); } } } else { for (SkFlagInfo* flag = SkCommandLineFlags::gHead; flag; flag = flag->next()) { for (int k = 0; k < helpFlags.count(); k++) { if (flag->name().equals(helpFlags[k]) || flag->shortName().equals(helpFlags[k])) { print_extended_help_for_flag(flag); helpFlags.remove(k); break; } } } } if (helpFlags.count() > 0) { SkDebugf("Requested help for unrecognized flags:\n"); for (int k = 0; k < helpFlags.count(); k++) { SkDebugf(" --%s\n", helpFlags[k]); } } helpPrinted = true; } if (!helpPrinted) { bool flagMatched = false; SkFlagInfo* flag = gHead; while (flag != nullptr) { if (flag->match(argv[i])) { flagMatched = true; switch (flag->getFlagType()) { case SkFlagInfo::kBool_FlagType: // Can be handled by match, above, but can also be set by the next // string. if (i+1 < argc && !SkStrStartsWith(argv[i+1], '-')) { i++; bool value; if (parse_bool_arg(argv[i], &value)) { flag->setBool(value); } } break; case SkFlagInfo::kString_FlagType: flag->resetStrings(); // Add all arguments until another flag is reached. while (i+1 < argc) { char* end = nullptr; // Negative numbers aren't flags. ignore_result(strtod(argv[i+1], &end)); if (end == argv[i+1] && SkStrStartsWith(argv[i+1], '-')) { break; } i++; flag->append(argv[i]); } break; case SkFlagInfo::kInt_FlagType: i++; flag->setInt(atoi(argv[i])); break; case SkFlagInfo::kDouble_FlagType: i++; flag->setDouble(atof(argv[i])); break; default: SkDEBUGFAIL("Invalid flag type"); } break; } flag = flag->next(); } if (!flagMatched) { #if SK_BUILD_FOR_MAC if (SkStrStartsWith(argv[i], "NSDocumentRevisions") || SkStrStartsWith(argv[i], "-NSDocumentRevisions")) { i++; // skip YES } else #endif if (FLAGS_undefok) { SkDebugf("FYI: ignoring unknown flag '%s'.\n", argv[i]); } else { SkDebugf("Got unknown flag '%s'. Exiting.\n", argv[i]); exit(-1); } } } } // Since all of the flags have been set, release the memory used by each // flag. FLAGS_x can still be used after this. SkFlagInfo* flag = gHead; gHead = nullptr; while (flag != nullptr) { SkFlagInfo* next = flag->next(); delete flag; flag = next; } if (helpPrinted) { exit(0); } }