|
44 | 44 | #include "rapidassist/timing.h" |
45 | 45 |
|
46 | 46 | #include "common.h" |
| 47 | +#include "wildcard.h" |
47 | 48 |
|
48 | 49 | using namespace bin2cpp; |
49 | 50 |
|
@@ -74,6 +75,8 @@ static const char * DEFAULT_BASECLASSNAME = "File"; |
74 | 75 | static const CppEncoderEnum DEFAULT_ENCODING = CPP_ENCODER_OCT; |
75 | 76 | static Dictionary identifiers_dictionary; // unique values for identifiers |
76 | 77 | static Dictionary output_files_dictionary; // unique values for output file names |
| 78 | +#define DIRECTORY_FILTER_SEPARATOR_STR ":" |
| 79 | +static const char DIRECTORY_FILTER_SEPARATOR = DIRECTORY_FILTER_SEPARATOR_STR[0]; |
77 | 80 |
|
78 | 81 | const char * getErrorCodeDescription(const APP_ERROR_CODES & error_code) |
79 | 82 | { |
@@ -159,40 +162,61 @@ void printUsage() |
159 | 162 | #endif |
160 | 163 |
|
161 | 164 | //usage string in docopt format. See http://docopt.org/ |
162 | | - static const char usage[] = |
| 165 | + static const char usage[] = |
163 | 166 | "Usage:\n" |
164 | 167 | " bin2cpp --file=<path> --output=<path> [--headerfile=<name>] [--identifier=<name>] [--generator=<name>] [--encoding=<name>] [--chunksize=<value>] [--namespace=<value>] [--baseclass=<name>] [--managerfile=<name>] [--registerfile] [--reportedfilepath=<value>] [--override] [--noheader] [--quiet]\n" |
165 | | - " bin2cpp --dir=<path> --output=<path> [--keepdirs] [--generator=<name>] [--encoding=<name>] [--chunksize=<value>] [--namespace=<value>] [--baseclass=<name>] [--managerfile=<name>] [--registerfile] [--override] [--noheader] [--quiet]\n" |
| 168 | + " bin2cpp --dir=<path> --output=<path> [--keepdirs] [--generator=<name>] [--encoding=<name>] [--chunksize=<value>] [--namespace=<value>] [--baseclass=<name>] [--managerfile=<name>] [--registerfile] [--dirincludefilter=<value>] [--direxcludefilter=<value>] [--override] [--noheader] [--quiet]\n" |
166 | 169 | " bin2cpp --help\n" |
167 | 170 | " bin2cpp --version\n" |
168 | 171 | "\n" |
169 | 172 | "Options:\n" |
170 | | - " --help Display this help message.\n" |
171 | | - " --version Display this application version.\n" |
172 | | - " --file=<path> Path of the input file used for embedding as C++ source code.\n" |
173 | | - " --dir=<path> Path of the input directory used for embedding all files of the directory as C++ source code.\n" |
174 | | - " --output=<path> Path of the output directory where to create generated code. ie: ." SEPARATOR "generated_files\n" |
175 | | - " --headerfile=<path> File name or relative path of the generated C++ header file. If a relative path from the output directory is specified,\n" |
176 | | - " the #include statement in the generated cpp file will match the relative path. ie: SplashScreen.h\n" |
177 | | - " Default value: input file name (without extension)\n" |
178 | | - " --identifier=<name> Identifier of the function name that is used to get an instance of the file. ie: SplashScreen\n" |
179 | | - " Default value is based on input file with format 'NameExt'.\n" |
180 | | - " --generator=<name> Name of the generator to use. Possible values are 'segment', 'string', 'array' and 'win32'. [default: segment]\n" |
181 | | - " --encoding=<name> Name of the binary to string literal encoding to use. Possible values are 'oct' and 'hex'. [default: oct]\n" |
182 | | - " --chunksize=<value> Size in bytes of each string segments (bytes per LoC). [default: 200]\n" |
183 | | - " --baseclass=<name> The name of the interface for embedded files. [default: File]\n" |
184 | | - " --namespace=<name> The namespace of the generated source code. [default: bin2cpp]\n" |
185 | | - " --reportedfilepath=<path> The relative reported path of the File. Path returned when calling method getFilePath() of the File class. ie: images" SEPARATOR "DCIM" SEPARATOR "IMG_0001.jpg.\n" |
186 | | - " Automatically calculated when --dir mode is used.\n" |
187 | | - " --managerfile=<path> File name or relative path of the generated C++ header file for the FileManager class. ie: FileManager.h\n" |
188 | | - " --registerfile Register the generated file to the FileManager class.\n" |
189 | | - " This flags is automatically set when parameter 'managerfile' is specified.\n" |
190 | | - " --keepdirs Keep the directory structure. Forces the output files to have the same\n" |
191 | | - " directory structure as the input files. Valid only when --dir is used.\n" |
192 | | - " --plainoutput Print the encoded string in plain format to stdout. Useful for scripts and integration with third party application.\n" |
193 | | - " --override Tells bin2cpp to overwrite the destination files.\n" |
194 | | - " --noheader Do not print program header to standard output.\n" |
195 | | - " --quiet Do not log any message to standard output.\n" |
| 173 | + " --help Display this help message.\n" |
| 174 | + " --version Display this application version.\n" |
| 175 | + " --file=<path> Path of the input file used for embedding as C++ source code.\n" |
| 176 | + " --dir=<path> Path of the input directory used for embedding all files of the directory as C++ source code.\n" |
| 177 | + " --output=<path> Path of the output directory where to create generated code. ie: ." SEPARATOR "generated_files\n" |
| 178 | + " --headerfile=<path> File name or relative path of the generated C++ header file. If a relative path from the output directory is specified,\n" |
| 179 | + " the #include statement in the generated cpp file will match the relative path. ie: SplashScreen.h\n" |
| 180 | + " Default value: input file name (without extension)\n" |
| 181 | + " --identifier=<name> Identifier of the function name that is used to get an instance of the file. ie: SplashScreen\n" |
| 182 | + " Default value is based on input file with format 'NameExt'.\n" |
| 183 | + " --generator=<name> Name of the generator to use. Possible values are 'segment', 'string', 'array' and 'win32'. [default: segment]\n" |
| 184 | + " --encoding=<name> Name of the binary to string literal encoding to use. Possible values are 'oct' and 'hex'. [default: oct]\n" |
| 185 | + " --chunksize=<value> Size in bytes of each string segments (bytes per LoC). [default: 200]\n" |
| 186 | + " --baseclass=<name> The name of the interface for embedded files. [default: File]\n" |
| 187 | + " --namespace=<name> The namespace of the generated source code. [default: bin2cpp]\n" |
| 188 | + " --reportedfilepath=<path> The relative reported path of the File. Path returned when calling method getFilePath() of the File class. ie: images" SEPARATOR "DCIM" SEPARATOR "IMG_0001.jpg.\n" |
| 189 | + " Automatically calculated when --dir mode is used.\n" |
| 190 | + " --managerfile=<path> File name or relative path of the generated C++ header file for the FileManager class. ie: FileManager.h\n" |
| 191 | + " --registerfile Register the generated file to the FileManager class.\n" |
| 192 | + " This flags is automatically set when parameter 'managerfile' is specified.\n" |
| 193 | + " --dirincludefilter=<value> Set a positive filter on the input directory to only select files matching the filter. Wildcard characters are accepted.\n" |
| 194 | + " Separate each filter with the character '" DIRECTORY_FILTER_SEPARATOR_STR "'. Valid only when --dir is used. See wildcard characters definition below.\n" |
| 195 | + " --direxcludefilter=<value> Set a negative filter on the input directory to skip files matching the filter. Wildcard characters are accepted.\n" |
| 196 | + " Separate each filter with the character '" DIRECTORY_FILTER_SEPARATOR_STR "'. Valid only when --dir is used. See wildcard characters definition below.\n" |
| 197 | + " The exclude filter has precedence over the inclusion filter.\n" |
| 198 | + " --keepdirs Keep the directory structure. Forces the output files to have the same\n" |
| 199 | + " directory structure as the input files. Valid only when --dir is used.\n" |
| 200 | + " --plainoutput Print the encoded string in plain format to stdout. Useful for scripts and integration with third party application.\n" |
| 201 | + " --override Tells bin2cpp to overwrite the destination files.\n" |
| 202 | + " --noheader Do not print program header to standard output.\n" |
| 203 | + " --quiet Do not log any message to standard output.\n" |
| 204 | + "\n" |
| 205 | + " Wildcard characters:\n" |
| 206 | + " '?' Matches any single character.\n" |
| 207 | + " '*' Matches zero or more characters.\n" |
| 208 | + " '#' Matches exactly one numeric digit (0-9).\n" |
| 209 | + " [charlist] Matches any single character inside the brackets.\n" |
| 210 | + " [a-z] Matches any single lowercase letter between 'a' and 'z'.\n" |
| 211 | + " [A-Z] Matches any single uppercase letter between 'A' and 'A'.\n" |
| 212 | + " [0-9] Matches any single digit between '0' and '9'.\n" |
| 213 | + " [a-zA-Z0-9] Matches any single letter (uppercase or lowercase) or digit.\n" |
| 214 | + "\n" |
| 215 | + " For example:\n" |
| 216 | + " 'ker*##.???' would match files that starts with 'ker', and ends with 2 digits, a dot and then 3 characters." |
| 217 | + " --dir-include-filter=\"*.jpg:*.png\" would include all files whose file extension is 'jpg' or 'png'.\n" |
| 218 | + " --dir-exclude-filter=\"*.bak\" would exclude all backup files.\n" |
| 219 | + " --dir-include-filter=\"*.log\" --dir-exclude-filter=\"debug.log\" would include all log files but not the one named 'debug.log'." |
196 | 220 | "\n"; |
197 | 221 | printf("%s", usage); |
198 | 222 | } |
@@ -352,6 +376,21 @@ int main(int argc, char* argv[]) |
352 | 376 |
|
353 | 377 | c.registerFiles = ra::cli::ParseArgument("registerfile", dummy, argc, argv); |
354 | 378 |
|
| 379 | + // directory include filters |
| 380 | + std::string filter; |
| 381 | + c.hasDirectoryIncludeFilters = ra::cli::ParseArgument("dirincludefilter", filter, argc, argv); |
| 382 | + if ( c.hasDirectoryIncludeFilters ) |
| 383 | + { |
| 384 | + strSplit(filter, DIRECTORY_FILTER_SEPARATOR, c.directoryIncludeFilters); |
| 385 | + } |
| 386 | + |
| 387 | + // directory exclude filters |
| 388 | + c.hasDirectoryExcludeFilters = ra::cli::ParseArgument("direxcludefilter", filter, argc, argv); |
| 389 | + if ( c.hasDirectoryExcludeFilters ) |
| 390 | + { |
| 391 | + strSplit(filter, DIRECTORY_FILTER_SEPARATOR, c.directoryExcludeFilters); |
| 392 | + } |
| 393 | + |
355 | 394 | //force registerfile if managerfile is specified |
356 | 395 | if (c.hasManagerFile) |
357 | 396 | { |
@@ -599,8 +638,28 @@ APP_ERROR_CODES processInputDirectory(const Context& c, bin2cpp::IGenerator * ge |
599 | 638 | for(size_t i=0; i<files.size(); i++) |
600 | 639 | { |
601 | 640 | const std::string & file = files[i]; |
602 | | - if (ra::filesystem::FileExists(file.c_str())) |
603 | | - tmp.push_back(file); |
| 641 | + |
| 642 | + // entry is not a file |
| 643 | + if ( !ra::filesystem::FileExists(file.c_str()) ) |
| 644 | + continue; |
| 645 | + |
| 646 | + // should we exclude the file? |
| 647 | + if ( c.hasDirectoryExcludeFilters ) |
| 648 | + { |
| 649 | + bool matches_any = bin2cpp::wildcard_match_any(file, c.directoryExcludeFilters); |
| 650 | + if ( matches_any ) |
| 651 | + continue; // force exclude this file. |
| 652 | + } |
| 653 | + |
| 654 | + // should we include the file? |
| 655 | + if ( c.hasDirectoryIncludeFilters ) |
| 656 | + { |
| 657 | + bool matches_any = bin2cpp::wildcard_match_any(file, c.directoryIncludeFilters); |
| 658 | + if ( !matches_any ) |
| 659 | + continue; // force not include this file. |
| 660 | + } |
| 661 | + |
| 662 | + tmp.push_back(file); |
604 | 663 | } |
605 | 664 | files = tmp; |
606 | 665 |
|
|
0 commit comments