OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkFlags.h" | 8 #include "SkFlags.h" |
9 | 9 |
10 SkFlagInfo* SkFlags::gHead; | 10 SkFlagInfo* SkFlags::gHead; |
11 SkString SkFlags::gUsage; | 11 SkString SkFlags::gUsage; |
12 | 12 |
13 void SkFlags::SetUsage(const char* usage) { | 13 void SkFlags::SetUsage(const char* usage) { |
14 gUsage.set(usage); | 14 gUsage.set(usage); |
15 } | 15 } |
16 | 16 |
17 // Maximum line length for the help message. | 17 // Maximum line length for the help message. |
18 #define LINE_LENGTH 80 | 18 #define LINE_LENGTH 80 |
19 | 19 |
| 20 static void print_help_for_flag(const SkFlagInfo* flag) { |
| 21 SkDebugf("\t--%s", flag->name().c_str()); |
| 22 const SkString& shortName = flag->shortName(); |
| 23 if (shortName.size() > 0) { |
| 24 SkDebugf(" or -%s", shortName.c_str()); |
| 25 } |
| 26 SkDebugf(":\ttype: %s", flag->typeAsString().c_str()); |
| 27 if (flag->defaultValue().size() > 0) { |
| 28 SkDebugf("\tdefault: %s", flag->defaultValue().c_str()); |
| 29 } |
| 30 SkDebugf("\n"); |
| 31 const SkString& help = flag->help(); |
| 32 size_t length = help.size(); |
| 33 const char* currLine = help.c_str(); |
| 34 const char* stop = currLine + length; |
| 35 while (currLine < stop) { |
| 36 if (strlen(currLine) < LINE_LENGTH) { |
| 37 // Only one line length's worth of text left. |
| 38 SkDebugf("\t\t%s\n", currLine); |
| 39 break; |
| 40 } |
| 41 int lineBreak = SkStrFind(currLine, "\n"); |
| 42 if (lineBreak < 0 || lineBreak > LINE_LENGTH) { |
| 43 // No line break within line length. Will need to insert one. |
| 44 // Find a space before the line break. |
| 45 int spaceIndex = LINE_LENGTH - 1; |
| 46 while (spaceIndex > 0 && currLine[spaceIndex] != ' ') { |
| 47 spaceIndex--; |
| 48 } |
| 49 int gap; |
| 50 if (0 == spaceIndex) { |
| 51 // No spaces on the entire line. Go ahead and break mid word. |
| 52 spaceIndex = LINE_LENGTH; |
| 53 gap = 0; |
| 54 } else { |
| 55 // Skip the space on the next line |
| 56 gap = 1; |
| 57 } |
| 58 SkDebugf("\t\t%.*s\n", spaceIndex, currLine); |
| 59 currLine += spaceIndex + gap; |
| 60 } else { |
| 61 // the line break is within the limit. Break there. |
| 62 lineBreak++; |
| 63 SkDebugf("\t\t%.*s", lineBreak, currLine); |
| 64 currLine += lineBreak; |
| 65 } |
| 66 } |
| 67 SkDebugf("\n"); |
| 68 } |
| 69 |
20 void SkFlags::ParseCommandLine(int argc, char** argv) { | 70 void SkFlags::ParseCommandLine(int argc, char** argv) { |
21 // Only allow calling this function once. | 71 // Only allow calling this function once. |
22 static bool gOnce; | 72 static bool gOnce; |
23 if (gOnce) { | 73 if (gOnce) { |
24 SkDebugf("ParseCommandLine should only be called once at the beginning" | 74 SkDebugf("ParseCommandLine should only be called once at the beginning" |
25 " of main!\n"); | 75 " of main!\n"); |
26 SkASSERT(false); | 76 SkASSERT(false); |
27 return; | 77 return; |
28 } | 78 } |
29 gOnce = true; | 79 gOnce = true; |
30 | 80 |
31 bool helpPrinted = false; | 81 bool helpPrinted = false; |
32 // Loop over argv, starting with 1, since the first is just the name of the
program. | 82 // Loop over argv, starting with 1, since the first is just the name of the
program. |
33 for (int i = 1; i < argc; i++) { | 83 for (int i = 1; i < argc; i++) { |
34 if (0 == strcmp("-h", argv[i]) || 0 == strcmp("--h", argv[i]) | 84 if (0 == strcmp("-h", argv[i]) || 0 == strcmp("--h", argv[i]) |
35 || 0 == strcmp("-help", argv[i]) || 0 == strcmp("--help", argv[i
])) { | 85 || 0 == strcmp("-help", argv[i]) || 0 == strcmp("--help", argv[i
])) { |
36 // Print help message. | 86 // Print help message. |
37 SkDebugf("%s\n%s\n", argv[0], gUsage.c_str()); | 87 SkTDArray<const char*> helpFlags; |
| 88 for (int j = i + 1; j < argc; j++) { |
| 89 if (SkStrStartsWith(argv[j], '-')) { |
| 90 break; |
| 91 } |
| 92 helpFlags.append(1, &argv[j]); |
| 93 } |
| 94 if (0 == helpFlags.count()) { |
| 95 // Only print general help message if help for specific flags is
not requested. |
| 96 SkDebugf("%s\n%s\n", argv[0], gUsage.c_str()); |
| 97 } |
38 SkDebugf("Flags:\n"); | 98 SkDebugf("Flags:\n"); |
39 SkFlagInfo* flag = SkFlags::gHead; | 99 SkFlagInfo* flag = SkFlags::gHead; |
40 while (flag != NULL) { | 100 while (flag != NULL) { |
41 SkDebugf("\t--%s:\ttype: %s", flag->name().c_str(), | 101 // If no flags followed --help, print them all |
42 flag->typeAsString().c_str()); | 102 bool printFlag = 0 == helpFlags.count(); |
43 if (flag->defaultValue().size() > 0) { | 103 if (!printFlag) { |
44 SkDebugf("\tdefault: %s", flag->defaultValue().c_str()); | 104 for (int k = 0; k < helpFlags.count(); k++) { |
45 } | 105 if (flag->name().equals(helpFlags[k]) || |
46 SkDebugf("\n"); | 106 flag->shortName().equals(helpFlags[k])) { |
47 const SkString& help = flag->help(); | 107 printFlag = true; |
48 size_t length = help.size(); | 108 helpFlags.remove(k); |
49 const char* currLine = help.c_str(); | 109 break; |
50 const char* stop = currLine + length; | |
51 while (currLine < stop) { | |
52 if (strlen(currLine) < LINE_LENGTH) { | |
53 // Only one line length's worth of text left. | |
54 SkDebugf("\t\t%s\n", currLine); | |
55 break; | |
56 } | |
57 int lineBreak = SkStrFind(currLine, "\n"); | |
58 if (lineBreak < 0 || lineBreak > LINE_LENGTH) { | |
59 // No line break within line length. Will need to insert
one. | |
60 // Find a space before the line break. | |
61 int spaceIndex = LINE_LENGTH - 1; | |
62 while (spaceIndex > 0 && currLine[spaceIndex] != ' ') { | |
63 spaceIndex--; | |
64 } | 110 } |
65 int gap; | |
66 if (0 == spaceIndex) { | |
67 // No spaces on the entire line. Go ahead and break
mid word. | |
68 spaceIndex = LINE_LENGTH; | |
69 gap = 0; | |
70 } else { | |
71 // Skip the space on the next line | |
72 gap = 1; | |
73 } | |
74 SkDebugf("\t\t%.*s\n", spaceIndex, currLine); | |
75 currLine += spaceIndex + gap; | |
76 } else { | |
77 // the line break is within the limit. Break there. | |
78 lineBreak++; | |
79 SkDebugf("\t\t%.*s", lineBreak, currLine); | |
80 currLine += lineBreak; | |
81 } | 111 } |
82 } | 112 } |
83 SkDebugf("\n"); | 113 if (printFlag) { |
| 114 print_help_for_flag(flag); |
| 115 } |
84 flag = flag->next(); | 116 flag = flag->next(); |
85 } | 117 } |
| 118 if (helpFlags.count() > 0) { |
| 119 SkDebugf("Requested help for unrecognized flags:\n"); |
| 120 for (int k = 0; k < helpFlags.count(); k++) { |
| 121 SkDebugf("\t--%s\n", helpFlags[k]); |
| 122 } |
| 123 } |
86 helpPrinted = true; | 124 helpPrinted = true; |
87 } | 125 } |
88 if (!helpPrinted) { | 126 if (!helpPrinted) { |
89 bool flagMatched = false; | 127 bool flagMatched = false; |
90 SkFlagInfo* flag = gHead; | 128 SkFlagInfo* flag = gHead; |
91 while (flag != NULL) { | 129 while (flag != NULL) { |
92 if (flag->match(argv[i])) { | 130 if (flag->match(argv[i])) { |
93 flagMatched = true; | 131 flagMatched = true; |
94 switch (flag->getFlagType()) { | 132 switch (flag->getFlagType()) { |
95 case SkFlagInfo::kBool_FlagType: | 133 case SkFlagInfo::kBool_FlagType: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 gHead = NULL; | 167 gHead = NULL; |
130 while (flag != NULL) { | 168 while (flag != NULL) { |
131 SkFlagInfo* next = flag->next(); | 169 SkFlagInfo* next = flag->next(); |
132 SkDELETE(flag); | 170 SkDELETE(flag); |
133 flag = next; | 171 flag = next; |
134 } | 172 } |
135 if (helpPrinted) { | 173 if (helpPrinted) { |
136 exit(0); | 174 exit(0); |
137 } | 175 } |
138 } | 176 } |
OLD | NEW |