bool parse_keep(std::vector<unique_ptr<Token>>::iterator* it, token keep_kind, std::vector<KeepSpec>* spec, bool mark_classes, bool mark_conditionally, bool allowshrinking, const std::string& filename, uint32_t line, bool* ok) { if ((**it)->type == keep_kind) { ++(*it); // Consume the keep token KeepSpec keep; keep.mark_classes = mark_classes; keep.mark_conditionally = mark_conditionally; keep.allowshrinking = allowshrinking; keep.source_filename = filename; keep.source_line = line; if (!parse_modifiers(it, &keep)) { skip_to_next_command(it); return true; } keep.class_spec = parse_class_specification(it, ok); spec->push_back(keep); return true; } return false; }
bool parse_keep(std::vector<unique_ptr<Token>>::iterator* it, token keep_kind, KeepSpecSet* spec, bool mark_classes, bool mark_conditionally, bool allowshrinking, const std::string& filename, uint32_t line, bool* ok) { if ((**it)->type == keep_kind) { ++(*it); // Consume the keep token auto keep = std::make_unique<KeepSpec>(); keep->mark_classes = mark_classes; keep->mark_conditionally = mark_conditionally; keep->allowshrinking = allowshrinking; keep->source_filename = filename; keep->source_line = line; if (!parse_modifiers(it, &*keep)) { skip_to_next_command(it); return true; } keep->class_spec = parse_class_specification(it, ok); spec->emplace(std::move(keep)); return true; } return false; }
bool ignore_class_specification_command( std::vector<unique_ptr<Token>>::iterator* it, token classspec_command) { if ((**it)->type != classspec_command) { return false; } ++(*it); // Ignore the rest of the unsupported comamnd. skip_to_next_command(it); return true; }
void parse(std::vector<unique_ptr<Token>>::iterator it, std::vector<unique_ptr<Token>>::iterator tokens_end, ProguardConfiguration* pg_config, unsigned int* parse_errors, const std::string& filename) { *parse_errors = 0; bool ok; while (it != tokens_end) { // Break out if we are at the end of the token stream. if ((*it)->type == token::eof_token) { break; } uint32_t line = (*it)->line; if (!(*it)->is_command()) { cerr << "Expecting command but found " << (*it)->show() << " at line " << (*it)->line << endl; ++it; skip_to_next_command(&it); continue; } // Input/Output Options if (parse_filepath_command(&it, token::include, pg_config->basedirectory, &pg_config->includes)) continue; if (parse_single_filepath_command( &it, token::basedirectory, &pg_config->basedirectory)) continue; if (parse_jars( &it, token::injars, pg_config->basedirectory, &pg_config->injars)) continue; if (parse_jars( &it, token::outjars, pg_config->basedirectory, &pg_config->outjars)) continue; if (parse_jars(&it, token::libraryjars, pg_config->basedirectory, &pg_config->libraryjars)) continue; // -skipnonpubliclibraryclasses not supported if ((*it)->type == token::dontskipnonpubliclibraryclasses) { // Silenty ignore the dontskipnonpubliclibraryclasses option. ++it; continue; } // -dontskipnonpubliclibraryclassmembers not supported if (parse_filepath_command(&it, token::keepdirectories, pg_config->basedirectory, &pg_config->keepdirectories)) continue; if (parse_target(&it, &pg_config->target_version)) continue; // -forceprocessing not supported // Keep Options if (parse_keep(&it, token::keep, &pg_config->keep_rules, true, // mark_classes false, // mark_conditionally false, // allowshrinking filename, line, &ok)) { if (!ok) { (*parse_errors)++; } continue; } if (parse_keep(&it, token::keepclassmembers, &pg_config->keep_rules, false, // mark_classes false, // mark_conditionally false, // allowshrinking filename, line, &ok)) { if (!ok) { (*parse_errors)++; } continue; } if (parse_keep(&it, token::keepclasseswithmembers, &pg_config->keep_rules, false, // mark_classes true, // mark_conditionally false, // allowshrinking filename, line, &ok)) { if (!ok) { (*parse_errors)++; } continue; } if (parse_keep(&it, token::keepnames, &pg_config->keep_rules, true, // mark_classes false, // mark_conditionally true, // allowshrinking filename, line, &ok)) { if (!ok) { (*parse_errors)++; } continue; } if (parse_keep(&it, token::keepclassmembernames, &pg_config->keep_rules, false, // mark_classes false, // mark_conditionally true, // allowshrinking filename, line, &ok)) { if (!ok) { (*parse_errors)++; } continue; } if (parse_keep(&it, token::keepclasseswithmembernames, &pg_config->keep_rules, false, // mark_classes true, // mark_conditionally true, // allowshrinking filename, line, &ok)) { if (!ok) { (*parse_errors)++; } continue; } if (parse_optional_filepath_command( &it, token::printseeds, &pg_config->printseeds)) continue; // Shrinking Options if (parse_bool_command(&it, token::dontshrink, false, &pg_config->shrink)) continue; if (parse_optional_filepath_command( &it, token::printusage, &pg_config->printusage)) continue; // Optimization Options if (parse_boolean_command( &it, token::dontoptimize, &pg_config->optimize, false)) continue; if (parse_filter_list_command( &it, token::optimizations, &pg_config->optimization_filters)) continue; if (parse_optimizationpasses_command(&it)) { continue; } if (parse_keep(&it, token::assumenosideeffects, &pg_config->assumenosideeffects_rules, false, // mark_classes false, // mark_conditionally false, // allowshrinking filename, line, &ok)) continue; if (parse_keep(&it, token::whyareyoukeeping, &pg_config->whyareyoukeeping_rules, false, // mark_classes false, // mark_conditionally false, // allowshrinking filename, line, &ok)) continue; // Obfuscation Options if ((*it)->type == token::dontobfuscate) { pg_config->dontobfuscate = true; ++it; continue; } // Redex ignores -dontskipnonpubliclibraryclasses if ((*it)->type == token::dontskipnonpubliclibraryclasses) { ++it; continue; } if (parse_optional_filepath_command( &it, token::printmapping, &pg_config->printmapping)) continue; if (parse_optional_filepath_command( &it, token::printconfiguration, &pg_config->printconfiguration)) continue; if (parse_allowaccessmodification(&it, &pg_config->allowaccessmodification)) continue; if (parse_dontusemixedcaseclassnames( &it, &pg_config->dontusemixedcaseclassnames)) continue; if (parse_filter_list_command( &it, token::keeppackagenames, &pg_config->keeppackagenames)) continue; if (parse_dontpreverify(&it, &pg_config->dontpreverify)) continue; if (parse_verbose(&it, &pg_config->verbose)) continue; if (parse_repackageclasses(&it)) continue; if (parse_filter_list_command(&it, token::dontwarn, &pg_config->dontwarn)) continue; if (parse_filter_list_command( &it, token::keepattributes, &pg_config->keepattributes)) continue; // Skip unknown token. if ((*it)->is_command()) { cerr << "Unimplemented command (skipping): " << (*it)->show() << " at line " << (*it)->line << endl; } else { cerr << "Unexpected token " << (*it)->show() << " at line " << (*it)->line << endl; (*parse_errors)++; } ++it; skip_to_next_command(&it); } }