ttextract.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /******************************************************************************
  2. *
  3. * project name: TI-68k Developer Utilities
  4. * file name: ttextract.c
  5. * initial date: 13/08/2000
  6. * author: thomas.nussbaumer@gmx.net
  7. * description: extracts a part of a file which starts after the starttoken
  8. * and ends just before the endtoken
  9. *
  10. ******************************************************************************/
  11. /*
  12. This file is part of TI-68k Developer Utilities.
  13. This file is free software; you can redistribute it and/or
  14. modify it under the terms of the GNU Lesser General Public
  15. License as published by the Free Software Foundation; either
  16. version 2.1 of the License, or (at your option) any later version.
  17. As a special exception, UNMODIFIED copies of ttextract may also be
  18. redistributed or sold without source code, for any purpose. (The Lesser
  19. General Public License restrictions do apply in other respects; for example,
  20. they cover modification of the program.) This exception notice must be
  21. removed on modified copies of this file.
  22. This program is distributed in the hope that it will be useful,
  23. but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  25. Lesser General Public License for more details.
  26. You should have received a copy of the GNU Lesser General Public
  27. License along with this library; if not, write to the Free Software
  28. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  29. */
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <ctype.h>
  33. #include "ttversion.h"
  34. #include "revtools.h"
  35. #ifdef FILE_REVISION
  36. #undef FILE_REVISION
  37. #endif
  38. #define FILE_REVISION "1.8"
  39. //=============================================================================
  40. // outputs usage information of this tool
  41. //=============================================================================
  42. void PrintUsage() {
  43. PRINT_ID("TTExtract");
  44. fprintf(USAGE_OUT, "Usage: ttextract [flags] <infile> <outfile> <starttoken> [<endtoken>]\n\n"\
  45. " -quiet .... don't output standard messages (unsets -v)\n" \
  46. " -v .... output additional messages (unsets -quiet)\n" \
  47. " -sh .... treat start token as hexcode\n" \
  48. " -eh .... treat end token as hexcode\n\n" \
  49. " Extract part of infile which starts right after the start token.\n"\
  50. " If an endtoken is given it ends just before the end token.\n" \
  51. " NOTE1: If you use -sh or -eh the given tokens have to be plain\n" \
  52. " hexcodes WITHOUT any prefix like \"0x\" or \"0h\"\n" \
  53. " NOTE2: if you want the extracted data to be correct, you have to\n"\
  54. " use -fno-unit-at-a-time, as long as this switch is\n" \
  55. " supported by GCC\n\n");
  56. }
  57. //=============================================================================
  58. // converts hex digit to number
  59. //=============================================================================
  60. unsigned char ConvHexDigit(unsigned char c) {
  61. c = tolower(c);
  62. if (c >= '0' && c <= '9') return c -'0';
  63. return c-'a'+10;
  64. }
  65. //=============================================================================
  66. // find given token in file
  67. //=============================================================================
  68. long FindToken(FILE* fp, char* token, int treat_as_hex) {
  69. int length = strlen(token);
  70. int i;
  71. int index = 0;
  72. int input;
  73. int found = 0;
  74. if (treat_as_hex) {
  75. if (length % 2 == 1) {
  76. fprintf(stderr,"ERROR: invalid length (%d) for hextoken (%s)\n",length,token);
  77. return -1;
  78. }
  79. for (i=0;i<length;i+=2) {
  80. if (isxdigit(token[i]) && isxdigit(token[i+1])) {
  81. token[i/2] = ConvHexDigit(token[i]) * 16 + ConvHexDigit(token[i+1]);
  82. }
  83. else {
  84. fprintf(stderr,"ERROR: invalid character in hextoken (%s)\n",token);
  85. return -1;
  86. }
  87. }
  88. length /= 2;
  89. }
  90. rewind(fp);
  91. // find start ....
  92. while ((input = fgetc(fp)) != EOF) {
  93. if (input == (unsigned char)token[index]) {
  94. index++;
  95. if (index == length) {
  96. found = 1;
  97. break;
  98. }
  99. }
  100. else {
  101. index = 0;
  102. if (input == token[0]) {
  103. index++;
  104. if (index == length) {
  105. found = 1;
  106. break;
  107. }
  108. }
  109. }
  110. }
  111. return (found) ? ftell(fp) : -2;
  112. }
  113. //=============================================================================
  114. // what should I say?
  115. //=============================================================================
  116. int main(int argc, char* argv[]) {
  117. FILE *infp;
  118. FILE *outfp;
  119. char *infile = NULL;
  120. char *outfile = NULL;
  121. char *starttoken = NULL;
  122. char *endtoken = NULL;
  123. long startpos;
  124. long endpos;
  125. int endtokenlength = 0; // 1.40: added initialization, hope it is correct.
  126. long count;
  127. int n;
  128. int hexstart = 0;
  129. int hexend = 0;
  130. int quiet = 0;
  131. int verbose = 0;
  132. if (argc < 4) {
  133. PrintUsage();
  134. return 1;
  135. }
  136. // parse arguments
  137. for (n=1; n<argc; n++) {
  138. if (!strcmp(argv[n], "-sh")) hexstart = 1;
  139. else if (!strcmp(argv[n], "-eh")) hexend = 1;
  140. else if (!strcmp(argv[n], "-quiet")) quiet=1,verbose=0;
  141. else if (!strcmp(argv[n], "-v")) verbose=1,quiet=0;
  142. else if (!infile) infile = argv[n];
  143. else if (!outfile) outfile = argv[n];
  144. else if (!starttoken) starttoken = argv[n];
  145. else if (!endtoken) endtoken = argv[n];
  146. else {
  147. PrintUsage();
  148. return 1;
  149. }
  150. }
  151. if (!infile || !outfile || !starttoken) {
  152. PrintUsage();
  153. return 1;
  154. }
  155. if (!quiet) PRINT_ID("TTExtract");
  156. if (endtoken) endtokenlength = strlen(endtoken);
  157. if (verbose) fprintf(stdout,"opening input file %s ...\n",infile);
  158. if (!(infp = fopen(infile,"rb"))) {
  159. fprintf(stderr,"ERROR: cannot open inputfile %s\n",infile);
  160. return 1;
  161. }
  162. startpos = FindToken(infp,starttoken,hexstart);
  163. if (startpos == -1) { // error
  164. fclose(infp);
  165. return 1;
  166. }
  167. if (startpos == -2) { // not found
  168. fprintf(stderr,"ERROR: position of start token not found\n");
  169. return 1;
  170. }
  171. if (verbose) fprintf(stdout,"starttoken (%s) found at position=%ld\n",starttoken,startpos);
  172. if (endtoken) {
  173. endpos = FindToken(infp,endtoken,hexend);
  174. if (endpos == -1) {
  175. fclose(infp);
  176. return 1;
  177. }
  178. if (endpos == -2) {
  179. fprintf(stderr,"ERROR: position of end token not found\n");
  180. return 1;
  181. }
  182. if (verbose) fprintf(stdout,"endtoken (%s) found at position=%ld\n",endtoken,endpos);
  183. if (hexend) endpos -= endtokenlength/2;
  184. else endpos -= endtokenlength;
  185. if (endpos <= startpos) {
  186. fprintf(stderr,"ERROR: endpos <= startpos\n");
  187. return 1;
  188. }
  189. }
  190. else {
  191. fseek(infp,0,SEEK_END);
  192. endpos = ftell(infp);
  193. if (verbose) fprintf(stdout,"using end-of-file as endposition (%ld)\n",endpos);
  194. }
  195. if (verbose) fprintf(stdout,"opening output file %s ...\n",outfile);
  196. if (!(outfp = fopen(outfile,"wb"))) {
  197. fprintf(stderr,"ERROR: cannot open outfile %s\n",argv[2]);
  198. fclose(infp);
  199. return 1;
  200. }
  201. fseek(infp,startpos,SEEK_SET);
  202. count = endpos - startpos;
  203. if (verbose) fprintf(stdout,"extracting %ld bytes ...\n",count);
  204. for (n=0;n<count;n++) fputc(fgetc(infp),outfp);
  205. fclose(infp);
  206. fclose(outfp);
  207. if (!quiet) fprintf(stdout,"%ld bytes written to %s\n",count,outfile);
  208. return 0;
  209. }
  210. //#############################################################################
  211. //###################### NO MORE FAKES BEYOND THIS LINE #######################
  212. //#############################################################################
  213. //
  214. //=============================================================================
  215. // Revision History
  216. //=============================================================================
  217. //
  218. // Revision 1.8 2009/01/25 Lionel Debroux
  219. // Changes by Romain Liévin and/or me for 64-bit compatibility.
  220. // Adapt to new version display (revtools.h).
  221. //
  222. // Revision 1.7 2005/08/22 Lionel Debroux.
  223. // Added a note about -fno-unit-at-a-time with GCC 4.0+ in the usage.
  224. //
  225. // Revision 1.6 2002/03/15 13:10:03 tnussb
  226. // usage text extended
  227. //
  228. // Revision 1.5 2002/03/15 13:00:51 tnussb
  229. // (1) closing of files added to end of program
  230. // (2) treatment of -v (verbose) added
  231. // (3) treatment of -quiet (suppress standard messages) added
  232. // (4) bug fixed (if no endtoken was given, a wrong endpos was evaluated)
  233. //
  234. // Revision 1.4 2002/02/07 09:49:37 tnussb
  235. // all local includes changed, because header files are now located in pctools folder
  236. //
  237. // Revision 1.3 2000/11/28 00:04:21 Thomas Nussbaumer
  238. // using now USAGE_OUT stream for usage info
  239. //
  240. // Revision 1.2 2000/08/23 19:55:02 Thomas Nussbaumer
  241. // adapted to automatic version display (revtools.h)
  242. //
  243. // Revision 1.1 2000/08/13 20:20:55 Thomas Nussbaumer
  244. // initial version
  245. //
  246. //