@@ -24,6 +24,18 @@ typedef NS_ENUM(NSUInteger, CDOutputColorMode) {
2424 CDOutputColorModeCaseCount
2525};
2626
27+ typedef NS_ENUM (NSUInteger , CDOptionBoolValue) {
28+ CDOptionBoolValueStripProtocolConformance = 0x100 ,
29+ CDOptionBoolValueStripOverrides,
30+ CDOptionBoolValueStripDuplicates,
31+ CDOptionBoolValueStripSynthesized,
32+ CDOptionBoolValueStripCtorMethod,
33+ CDOptionBoolValueStripDtorMethod,
34+ CDOptionBoolValueAddSymbolImageComments,
35+
36+ CDOptionBoolValueCaseEnd
37+ };
38+
2739static void printUsage (const char *progname) {
2840 printf (" Usage: %s [options]\n "
2941 " Options:\n "
@@ -51,6 +63,24 @@ static void printUsage(const char *progname) {
5163 " -j <N>, --jobs=<N> Allow N jobs at once\n "
5264 " only applicable when specified with -a/--dyld_shared_cache\n "
5365 " (defaults to number of processing core available)\n "
66+ " \n "
67+ " --strip-protocol-conformance[=flag] Hide properties and methods\n "
68+ " that are required by a protocol the type conforms to\n "
69+ " (defaults to false)\n "
70+ " --strip-overrides[=flag] Hide properties and methods\n "
71+ " that are inherited from the class hierachy\n "
72+ " (defaults to false)\n "
73+ " --strip-duplicates[=flag] Hide duplicate occurrences of a property or method\n "
74+ " (defaults to false)\n "
75+ " --strip-synthesized[=flag] Hide methods and ivars that are synthesized from a property\n "
76+ " (defaults to true)\n "
77+ " --strip-ctor-method[=flag] Hide `.cxx_construct` method\n "
78+ " (defaults to false)\n "
79+ " --strip-dtor-method[=flag] Hide `.cxx_destruct` method\n "
80+ " (defaults to false)\n "
81+ " --add-symbol-comments[=flag] Add comments above each eligible declaration\n "
82+ " with the symbol name and image path the object is found in\n "
83+ " (defaults to false)\n "
5484 " " , progname);
5585}
5686
@@ -245,6 +275,33 @@ static void printUsage(const char *progname) {
245275 return [semanticString string ];
246276}
247277
278+ // / - Returns: `0` if `value` should be handled as `NO`,
279+ // / `1` if `value` should be handled as `YES`,
280+ // / `-1` if there's an error processing `value`
281+ static int parseOptargBool (const char *const value) {
282+ // no value means enable the flag
283+ if (value == NULL ) { return 1 ; }
284+
285+ if (strcmp (value, " 0" ) == 0 ) { return 0 ; }
286+ if (strcmp (value, " 1" ) == 0 ) { return 1 ; }
287+ if (strcmp (value, " no" ) == 0 ) { return 0 ; }
288+ if (strcmp (value, " yes" ) == 0 ) { return 1 ; }
289+ if (strcmp (value, " NO" ) == 0 ) { return 0 ; }
290+ if (strcmp (value, " YES" ) == 0 ) { return 1 ; }
291+ if (strcmp (value, " N" ) == 0 ) { return 0 ; }
292+ if (strcmp (value, " Y" ) == 0 ) { return 1 ; }
293+ if (strcmp (value, " n" ) == 0 ) { return 0 ; }
294+ if (strcmp (value, " y" ) == 0 ) { return 1 ; }
295+ if (strcmp (value, " off" ) == 0 ) { return 0 ; }
296+ if (strcmp (value, " on" ) == 0 ) { return 1 ; }
297+ if (strcmp (value, " false" ) == 0 ) { return 0 ; }
298+ if (strcmp (value, " true" ) == 0 ) { return 1 ; }
299+ if (strcmp (value, " FALSE" ) == 0 ) { return 0 ; }
300+ if (strcmp (value, " TRUE" ) == 0 ) { return 1 ; }
301+
302+ return -1 ;
303+ }
304+
248305int main (int argc, char *argv[]) {
249306 BOOL dyldSharedCacheFlag = NO ;
250307 BOOL listFlag = NO ;
@@ -255,6 +312,9 @@ int main(int argc, char *argv[]) {
255312 NSMutableArray <NSString *> *requestProtocolList = [NSMutableArray array ];
256313 NSUInteger maxJobs = NSProcessInfo .processInfo .processorCount ;
257314
315+ CDGenerationOptions *const generationOptions = [CDGenerationOptions new ];
316+ generationOptions.stripSynthesized = YES ;
317+
258318 struct option const options[] = {
259319 { " dyld_shared_cache" , no_argument, NULL , ' a' },
260320 { " list" , no_argument, NULL , ' l' },
@@ -264,12 +324,77 @@ int main(int argc, char *argv[]) {
264324 { " class" , required_argument, NULL , ' c' },
265325 { " protocol" , required_argument, NULL , ' p' },
266326 { " jobs" , required_argument, NULL , ' j' },
267- { NULL , 0 , NULL , 0 }
327+
328+ { " strip-protocol-conformance" , optional_argument, NULL , CDOptionBoolValueStripProtocolConformance },
329+ { " strip-overrides" , optional_argument, NULL , CDOptionBoolValueStripOverrides },
330+ { " strip-duplicates" , optional_argument, NULL , CDOptionBoolValueStripDuplicates },
331+ { " strip-synthesized" , optional_argument, NULL , CDOptionBoolValueStripSynthesized },
332+ { " strip-ctor-method" , optional_argument, NULL , CDOptionBoolValueStripCtorMethod },
333+ { " strip-dtor-method" , optional_argument, NULL , CDOptionBoolValueStripDtorMethod },
334+ { " add-symbol-comments" , optional_argument, NULL , CDOptionBoolValueAddSymbolImageComments },
335+
336+ { NULL , 0 , NULL , 0 }
268337 };
269338
339+ int optionIndex = 0 ;
270340 int ch;
271- while ((ch = getopt_long (argc, argv, " :alo:m:i:c:p:j:" , options, NULL )) != -1 ) {
341+ while ((ch = getopt_long (argc, argv, " :alo:m:i:c:p:j:" , options, &optionIndex )) != -1 ) {
272342 switch (ch) {
343+ case CDOptionBoolValueStripProtocolConformance:
344+ case CDOptionBoolValueStripOverrides:
345+ case CDOptionBoolValueStripDuplicates:
346+ case CDOptionBoolValueStripSynthesized:
347+ case CDOptionBoolValueStripCtorMethod:
348+ case CDOptionBoolValueStripDtorMethod:
349+ case CDOptionBoolValueAddSymbolImageComments: {
350+ struct option const *const option = options + optionIndex;
351+ // test if we want to consume the next argument.
352+ // `optional_argument` only provides `optarg` if the
353+ // command line paramter is in the format "--name=value",
354+ // this code allows us to consume "--name" "value".
355+ // We have to validate "value", otherwise we might accidently
356+ // consume "--name" "--flag"
357+ if (optarg == NULL && optind < argc) {
358+ int const parse = parseOptargBool (argv[optind]);
359+ // sucessful parse - consume next arg
360+ if (parse >= 0 ) {
361+ optarg = argv[optind];
362+ optind++;
363+ }
364+ }
365+ int const parse = parseOptargBool (optarg);
366+ if (parse < 0 ) {
367+ fprintf (stderr, " Unknown value for --%s : '%s ', expected 'yes', 'no'\n " , option->name , optarg);
368+ return 1 ;
369+ }
370+
371+ BOOL const flag = (parse != 0 );
372+ switch (ch) {
373+ case CDOptionBoolValueStripProtocolConformance:
374+ generationOptions.stripProtocolConformance = flag;
375+ break ;
376+ case CDOptionBoolValueStripOverrides:
377+ generationOptions.stripOverrides = flag;
378+ break ;
379+ case CDOptionBoolValueStripDuplicates:
380+ generationOptions.stripDuplicates = flag;
381+ break ;
382+ case CDOptionBoolValueStripSynthesized:
383+ generationOptions.stripSynthesized = flag;
384+ break ;
385+ case CDOptionBoolValueStripCtorMethod:
386+ generationOptions.stripCtorMethod = flag;
387+ break ;
388+ case CDOptionBoolValueStripDtorMethod:
389+ generationOptions.stripDtorMethod = flag;
390+ break ;
391+ case CDOptionBoolValueAddSymbolImageComments:
392+ generationOptions.addSymbolImageComments = flag;
393+ break ;
394+ default :
395+ break ;
396+ }
397+ } break ;
273398 case ' a' :
274399 dyldSharedCacheFlag = YES ;
275400 break ;
@@ -329,9 +454,6 @@ int main(int argc, char *argv[]) {
329454 return 1 ;
330455 }
331456
332- CDGenerationOptions *const generationOptions = [CDGenerationOptions new ];
333- generationOptions.stripSynthesized = YES ;
334-
335457 IMP const blankIMP = imp_implementationWithBlock (^{ }); // returns void, takes no parameters
336458
337459 // just doing this once before we potentially delete some class initializers
0 commit comments