tthex2bin.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /******************************************************************************
  2. *
  3. * project name: TI-68k Developer Utilities
  4. * file name: tthex2bin.c
  5. * initial date: 18/03/2002
  6. * author: thomas.nussbaumer@gmx.net
  7. * description: converts textfile with hex data into binary file
  8. *
  9. ******************************************************************************/
  10. /*
  11. This file is part of TI-68k Developer Utilities.
  12. This file is free software; you can redistribute it and/or
  13. modify it under the terms of the GNU Lesser General Public
  14. License as published by the Free Software Foundation; either
  15. version 2.1 of the License, or (at your option) any later version.
  16. As a special exception, UNMODIFIED copies of tthex2bin may also be
  17. redistributed or sold without source code, for any purpose. (The Lesser
  18. General Public License restrictions do apply in other respects; for example,
  19. they cover modification of the program.) This exception notice must be
  20. removed on modified copies of this file.
  21. This program is distributed in the hope that it will be useful,
  22. but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  24. Lesser General Public License for more details.
  25. You should have received a copy of the GNU Lesser General Public
  26. License along with this library; if not, write to the Free Software
  27. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. */
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include <ctype.h>
  33. #include "ttversion.h"
  34. #include "revtools.h"
  35. #include "tt.h"
  36. #ifdef FILE_REVISION
  37. #undef FILE_REVISION
  38. #endif
  39. #define FILE_REVISION "1.3"
  40. //=============================================================================
  41. // outputs usage information of this tool
  42. //=============================================================================
  43. void PrintUsage() {
  44. PRINT_ID("TTHex2Bin");
  45. fprintf(USAGE_OUT, "Usage: tthex2bin [flags] <infile> <outfile>\n\n" \
  46. " -quiet .... don't output standard messages\n" \
  47. " -binary .... infile contains binary numbers\n" \
  48. " infile .... name of input file (use '-' for stdin)\n" \
  49. " outfile .... name of output file\n\n" \
  50. " Converts text file with hex data to binary file. The numbers\n" \
  51. " in the inputfile must be prefixed with \"0x\" and must have\n" \
  52. " ALL the same length (2,4 or 8 hexdigits). Valid separators are\n" \
  53. " spaces, commas, linebreaks and TABs.\n" \
  54. " Empty lines are valid. Lines starting with \"//\" or \"#\" are\n" \
  55. " ignored (comment lines). Example of an inputline:\n" \
  56. " 0x1234,0x5678,0x9ABC,0xdfab\n" \
  57. " Binary mode: binary numbers have to be prefixed with \"0b\".\n" \
  58. " Only binary numbers with 8, 16 or 32 digits are valid.\n" \
  59. " You cannot mix binary and hexnumbers in one inputfile. Example:\n"\
  60. " 0b11110000 0b10101010 0b11111111\n\n");
  61. }
  62. #define IS_COMMA_OR_WHITESPACE_NOTNULL(i) (((i) == '\t' || (i) == ' ' || (i) == ',' || (i) == '\n' || (i) == '\r') && (i))
  63. //=============================================================================
  64. // skips white spaces and commas of buffer ... return pointer to new position
  65. //=============================================================================
  66. unsigned char* SkipWhiteSpaces(unsigned char* buffer) {
  67. while (IS_COMMA_OR_WHITESPACE_NOTNULL(*buffer)) buffer++;
  68. return buffer;
  69. }
  70. //=============================================================================
  71. // read a hex number of form 0xHHHHHHH .... where H are hexdigits
  72. //=============================================================================
  73. unsigned char* ReadHexNumber(unsigned char* buffer,unsigned long* data,int *len) {
  74. unsigned char b[65536];
  75. *len = 0;
  76. if (!*buffer) return NULL;
  77. if (*buffer != '0' || *(buffer+1) != 'x') {
  78. *len = -1;
  79. fprintf(stderr,"ERROR: missing prefix \"0b\" of binary number [%s]\n",buffer);
  80. return NULL;
  81. }
  82. buffer+=2;
  83. while (isxdigit(*buffer)) {
  84. b[*len] = *buffer++;
  85. (*len)++;
  86. }
  87. b[*len] = 0;
  88. if ((*len) %2) {
  89. fprintf(stderr,"ERROR: odd numbers (%d) of digits not allowed in hexnumber\n",*len);
  90. *len = -1;
  91. return NULL;
  92. }
  93. *data = strtoul((char *)b,NULL,16);
  94. *len /= 2;
  95. return buffer;
  96. }
  97. #define isbdigit(c) (c=='0' || c=='1')
  98. //=============================================================================
  99. // read a binary number of form 0xb1101010 s
  100. //=============================================================================
  101. unsigned char* ReadBinNumber(unsigned char* buffer,unsigned long* data,int *len) {
  102. unsigned char b[65536];
  103. *len = 0;
  104. if (!*buffer) return NULL;
  105. if (*buffer != '0' || *(buffer+1) != 'b') {
  106. *len = -1;
  107. fprintf(stderr,"ERROR: missing prefix \"0b\" of binary number\n");
  108. return NULL;
  109. }
  110. buffer+=2;
  111. while (isbdigit(*buffer)) {
  112. b[*len] = *buffer++;
  113. (*len)++;
  114. }
  115. b[*len] = 0;
  116. if ((*len) % 8) {
  117. fprintf(stderr,"ERROR: length of binary number (%d) not a multiple of 8\n",*len);
  118. *len = -1;
  119. return NULL;
  120. }
  121. *len /= 8;
  122. *data = strtoul((char *)b,NULL,2);
  123. return buffer;
  124. }
  125. //=============================================================================
  126. // convert hexcode input into binary output
  127. //=============================================================================
  128. long ConvertHex2Bin(FILE* ifp, FILE* ofp,int binary) {
  129. unsigned char buffer[65536];
  130. long bytes_processed = 0;
  131. int nr_bytes = 0;
  132. unsigned long data;
  133. int nr_tmp;
  134. unsigned char* ptr;
  135. while (fgets((char *)buffer,65535,ifp)) {
  136. ptr = SkipWhiteSpaces(buffer);
  137. if (!*ptr) continue;
  138. if ((*ptr == '/' && *(ptr+1) == '/') || *ptr == '#') continue;
  139. do {
  140. ptr = SkipWhiteSpaces(ptr);
  141. if (!*ptr) break;
  142. //printf("converting [%s]",ptr);
  143. ptr = (binary) ? ReadBinNumber(ptr,&data,&nr_tmp) : ReadHexNumber(ptr,&data, &nr_tmp);
  144. //printf("nr=0x%08X prev_bytes=%d act_bytes=%d\n",data,nr_bytes,nr_tmp);
  145. if (nr_tmp == -1) return -1;
  146. if (nr_tmp == 0) break;
  147. if (!nr_bytes && !nr_tmp) continue;
  148. if (!nr_bytes) {
  149. nr_bytes = nr_tmp;
  150. }
  151. else if (nr_bytes != nr_tmp) {
  152. fprintf(stderr,"ERROR: missmatch in length of hexnumbers\n");
  153. return -1;
  154. }
  155. if (nr_bytes == 1) {
  156. fputc(data & 0xff,ofp);
  157. }
  158. else if (nr_bytes == 2) {
  159. fputc((data >> 8) & 0xff,ofp);
  160. fputc(data & 0xff,ofp);
  161. }
  162. else if (nr_bytes == 4) {
  163. fputc((data >> 24) & 0xff,ofp);
  164. fputc((data >> 16) & 0xff,ofp);
  165. fputc((data >> 8) & 0xff,ofp);
  166. fputc(data & 0xff,ofp);
  167. }
  168. else {
  169. if (binary) {
  170. fprintf(stderr,"ERROR: only hexnumbers with 2, 4, or 8 digits are valid\n");
  171. }
  172. else {
  173. fprintf(stderr,"ERROR: only binarynumbers with 8, 16, or 32 digits are valid\n");
  174. }
  175. return -1;
  176. }
  177. bytes_processed+=nr_bytes;
  178. }
  179. while (1);
  180. }
  181. return bytes_processed;
  182. }
  183. //=============================================================================
  184. // ... another "just a main routine" tool ...
  185. //=============================================================================
  186. int main(int argc,char *argv[]) {
  187. char* infile = NULL;
  188. char* outfile = NULL;
  189. FILE* ifp;
  190. FILE* ofp;
  191. int quiet = 0;
  192. int binary_mode = 0;
  193. long bytes_processed;
  194. int n;
  195. // check for too less arguments
  196. if (argc < 3) {
  197. PrintUsage();
  198. return 1;
  199. }
  200. // parse arguments
  201. for (n=1; n<argc; n++) {
  202. if (!strcmp(argv[n], "-quiet")) quiet = 1;
  203. else if (!strcmp(argv[n], "-binary")) binary_mode = 1;
  204. else if (!infile) infile = argv[n];
  205. else if (!outfile) outfile = argv[n];
  206. else {
  207. PrintUsage();
  208. return 1;
  209. }
  210. }
  211. if (!infile || !outfile) {
  212. PrintUsage();
  213. return 1;
  214. }
  215. if (!strcmp(infile,"-")) {
  216. if (!quiet) fprintf(stdout,"using stdin as input\n");
  217. ifp = stdin;
  218. }
  219. else {
  220. if (!(ifp = fopen(infile,"r"))) {
  221. fprintf(stderr,"ERROR: cannot open inputfile %s\n",infile);
  222. return 1;
  223. }
  224. }
  225. if (!quiet) PRINT_ID("TTBin2Hex");
  226. if (!(ofp = fopen(outfile,"wb"))) {
  227. fprintf(stderr,"ERROR: cannot open outputfile %s\n",outfile);
  228. if (ifp != stdin) fclose(ifp);
  229. return 1;
  230. }
  231. bytes_processed = ConvertHex2Bin(ifp,ofp,binary_mode);
  232. if (ifp != stdin) fclose(ifp);
  233. fclose(ofp);
  234. if (bytes_processed == -1) {
  235. remove(outfile);
  236. return 1;
  237. }
  238. if (!quiet) fprintf(stdout,"%ld bytes written to %s\n",bytes_processed,outfile);
  239. return 0;
  240. }
  241. //#############################################################################
  242. //###################### NO MORE FAKES BEYOND THIS LINE #######################
  243. //#############################################################################
  244. //
  245. //=============================================================================
  246. // Revision History
  247. //=============================================================================
  248. //
  249. // Revision 1.3 2009/01/25 Lionel Debroux
  250. // Changes by Romain Liévin and/or me for 64-bit compatibility.
  251. // Adapt to new version display (revtools.h).
  252. //
  253. // Revision 1.2 2002/03/19 09:41:22 tnussb
  254. // new mode "convert binary numbers" added
  255. //
  256. // Revision 1.1 2002/03/18 12:54:23 tnussb
  257. // initial version
  258. //
  259. //