args.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright (C) 2006-2007 Michael Buesch <m@bues.ch>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include "args.h"
  14. #include "main.h"
  15. #include "util.h"
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <fcntl.h>
  20. #include <unistd.h>
  21. struct cmdline_args cmdargs = {
  22. .debug = 0,
  23. .arch = 5,
  24. .informat = FMT_B43,
  25. .print_addresses = 0,
  26. .unknown_decode = 0,
  27. };
  28. #define ARG_MATCH 0
  29. #define ARG_NOMATCH 1
  30. #define ARG_ERROR -1
  31. static int do_cmp_arg(char **argv, int *pos,
  32. const char *template,
  33. int allow_merged,
  34. char **param)
  35. {
  36. char *arg;
  37. char *next_arg;
  38. size_t arg_len, template_len;
  39. arg = argv[*pos];
  40. next_arg = argv[*pos + 1];
  41. arg_len = strlen(arg);
  42. template_len = strlen(template);
  43. if (param) {
  44. /* Maybe we have a merged parameter here.
  45. * A merged parameter is "-pfoobar" for example.
  46. */
  47. if (allow_merged && arg_len > template_len) {
  48. if (memcmp(arg, template, template_len) == 0) {
  49. *param = arg + template_len;
  50. return ARG_MATCH;
  51. }
  52. return ARG_NOMATCH;
  53. } else if (arg_len != template_len)
  54. return ARG_NOMATCH;
  55. *param = next_arg;
  56. }
  57. if (strcmp(arg, template) == 0) {
  58. if (param) {
  59. /* Skip the parameter on the next iteration. */
  60. (*pos)++;
  61. if (*param == NULL) {
  62. fprintf(stderr, "%s needs a parameter\n", arg);
  63. return ARG_ERROR;
  64. }
  65. }
  66. return ARG_MATCH;
  67. }
  68. return ARG_NOMATCH;
  69. }
  70. /* Simple and lean command line argument parsing. */
  71. static int cmp_arg(char **argv, int *pos,
  72. const char *long_template,
  73. const char *short_template,
  74. char **param)
  75. {
  76. int err;
  77. if (long_template) {
  78. err = do_cmp_arg(argv, pos, long_template, 0, param);
  79. if (err == ARG_MATCH || err == ARG_ERROR)
  80. return err;
  81. }
  82. err = ARG_NOMATCH;
  83. if (short_template)
  84. err = do_cmp_arg(argv, pos, short_template, 1, param);
  85. return err;
  86. }
  87. static void usage(FILE *fd, int argc, char **argv)
  88. {
  89. fprintf(fd, "Usage: %s INPUT_FILE OUTPUT_FILE [OPTIONS]\n", argv[0]);
  90. fprintf(fd, " -a|--arch ARCH The architecture type of the input file (5 or 15)\n");
  91. fprintf(fd, " -f|--format FMT Input file format. FMT must be one of:\n");
  92. fprintf(fd, " raw-le32, raw-be32, b43\n");
  93. fprintf(fd, " -p|--paddr Print the code addresses\n");
  94. fprintf(fd, " -u|--unkdec Decode operands of unknown instructions\n");
  95. fprintf(fd, " -d|--debug Print verbose debugging info\n");
  96. fprintf(fd, " Repeat for more verbose debugging\n");
  97. fprintf(fd, " -h|--help Print this help\n");
  98. }
  99. int parse_args(int argc, char **argv)
  100. {
  101. int i;
  102. int res;
  103. char *param;
  104. infile_name = NULL;
  105. outfile_name = NULL;
  106. for (i = 1; i < argc; i++) {
  107. if ((res = cmp_arg(argv, &i, "--help", "-h", NULL)) == ARG_MATCH) {
  108. usage(stdout, argc, argv);
  109. return 1;
  110. } else if ((res = cmp_arg(argv, &i, "--format", "-f", &param)) == ARG_MATCH) {
  111. if (strcasecmp(param, "raw-le32") == 0)
  112. cmdargs.informat = FMT_RAW_LE32;
  113. else if (strcasecmp(param, "raw-be32") == 0)
  114. cmdargs.informat = FMT_RAW_BE32;
  115. else if (strcasecmp(param, "b43") == 0)
  116. cmdargs.informat = FMT_B43;
  117. else {
  118. fprintf(stderr, "Invalid -f|--format\n");
  119. return -1;
  120. }
  121. } else if ((res = cmp_arg(argv, &i, "--paddr", "-p", NULL)) == ARG_MATCH) {
  122. cmdargs.print_addresses = 1;
  123. } else if ((res = cmp_arg(argv, &i, "--unkdec", "-u", NULL)) == ARG_MATCH) {
  124. cmdargs.unknown_decode = 1;
  125. } else if ((res = cmp_arg(argv, &i, "--debug", "-d", NULL)) == ARG_MATCH) {
  126. cmdargs.debug++;
  127. } else if ((res = cmp_arg(argv, &i, "--arch", "-a", &param)) == ARG_MATCH) {
  128. unsigned long arch;
  129. char *tail;
  130. arch = strtol(param, &tail, 0);
  131. if (strlen(tail) || (arch != 5 && arch != 15)) {
  132. fprintf(stderr, "Unsupported architecture \"%s\"\n",
  133. param);
  134. return -1;
  135. }
  136. cmdargs.arch = arch;
  137. } else {
  138. if (!infile_name) {
  139. infile_name = argv[i];
  140. continue;
  141. }
  142. if (!outfile_name) {
  143. outfile_name = argv[i];
  144. continue;
  145. }
  146. fprintf(stderr, "Unrecognized argument: %s\n", argv[i]);
  147. goto out_usage;
  148. }
  149. }
  150. if (!infile_name || !outfile_name)
  151. goto out_usage;
  152. return 0;
  153. out_usage:
  154. usage(stderr, argc, argv);
  155. return -1;
  156. }
  157. int open_input_file(void)
  158. {
  159. if (strcmp(infile_name, "-") == 0) {
  160. infile = stdin;
  161. } else {
  162. infile = fopen(infile_name, "r");
  163. if (!infile) {
  164. fprintf(stderr, "Could not open INPUT_FILE %s\n",
  165. infile_name);
  166. return -1;
  167. }
  168. }
  169. return 0;
  170. }
  171. void close_input_file(void)
  172. {
  173. if (strcmp(infile_name, "-") != 0)
  174. fclose(infile);
  175. }
  176. int open_output_file(void)
  177. {
  178. if (strcmp(outfile_name, "-") == 0) {
  179. outfile = stdout;
  180. } else {
  181. outfile = fopen(outfile_name, "w+");
  182. if (!outfile) {
  183. fprintf(stderr, "Could not open OUTPUT_FILE %s\n",
  184. outfile_name);
  185. return -1;
  186. }
  187. }
  188. return 0;
  189. }
  190. void close_output_file(void)
  191. {
  192. if (strcmp(outfile_name, "-") != 0)
  193. fclose(outfile);
  194. }