args.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * Copyright (C) 2006-2010 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. .print_sizes = 0,
  24. .initvals_fn_extension = ".initvals",
  25. .outformat = FMT_B43,
  26. };
  27. #define ARG_MATCH 0
  28. #define ARG_NOMATCH 1
  29. #define ARG_ERROR -1
  30. static int do_cmp_arg(char **argv, int *pos,
  31. const char *template,
  32. int allow_merged,
  33. const char **param)
  34. {
  35. char *arg;
  36. char *next_arg;
  37. size_t arg_len, template_len;
  38. arg = argv[*pos];
  39. next_arg = argv[*pos + 1];
  40. arg_len = strlen(arg);
  41. template_len = strlen(template);
  42. if (param) {
  43. /* Maybe we have a merged parameter here.
  44. * A merged parameter is "-pfoobar" for example.
  45. */
  46. if (allow_merged && arg_len > template_len) {
  47. if (memcmp(arg, template, template_len) == 0) {
  48. *param = arg + template_len;
  49. return ARG_MATCH;
  50. }
  51. return ARG_NOMATCH;
  52. } else if (arg_len != template_len)
  53. return ARG_NOMATCH;
  54. *param = next_arg;
  55. }
  56. if (strcmp(arg, template) == 0) {
  57. if (param) {
  58. /* Skip the parameter on the next iteration. */
  59. (*pos)++;
  60. if (*param == NULL) {
  61. fprintf(stderr, "%s needs a parameter\n", arg);
  62. return ARG_ERROR;
  63. }
  64. }
  65. return ARG_MATCH;
  66. }
  67. return ARG_NOMATCH;
  68. }
  69. /* Simple and lean command line argument parsing. */
  70. static int cmp_arg(char **argv, int *pos,
  71. const char *long_template,
  72. const char *short_template,
  73. const char **param)
  74. {
  75. int err;
  76. if (long_template) {
  77. err = do_cmp_arg(argv, pos, long_template, 0, param);
  78. if (err == ARG_MATCH || err == ARG_ERROR)
  79. return err;
  80. }
  81. err = ARG_NOMATCH;
  82. if (short_template)
  83. err = do_cmp_arg(argv, pos, short_template, 1, param);
  84. return err;
  85. }
  86. static void usage(void)
  87. {
  88. printf("Usage: b43-asm INPUT_FILE OUTPUT_FILE [OPTIONS]\n");
  89. printf(" -f|--format FMT Output file format. FMT must be one of:\n");
  90. printf(" raw-le32, raw-be32, b43\n");
  91. printf(" -d|--debug Print verbose debugging info\n");
  92. printf(" Repeat for more verbose debugging\n");
  93. printf(" -s|--psize Print the size of the code after assembling\n");
  94. printf(" -e|--ivalext EXT Filename extension for the initvals\n");
  95. printf(" -h|--help Print this help\n");
  96. }
  97. int parse_args(int argc, char **argv)
  98. {
  99. int i;
  100. int res;
  101. const char *param;
  102. if (argc < 3)
  103. goto out_usage;
  104. infile_name = argv[1];
  105. outfile_name = argv[2];
  106. for (i = 3; i < argc; i++) {
  107. if ((res = cmp_arg(argv, &i, "--help", "-h", NULL)) == ARG_MATCH) {
  108. usage();
  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.outformat = FMT_RAW_LE32;
  113. else if (strcasecmp(param, "raw-be32") == 0)
  114. cmdargs.outformat = FMT_RAW_BE32;
  115. else if (strcasecmp(param, "b43") == 0)
  116. cmdargs.outformat = FMT_B43;
  117. else {
  118. fprintf(stderr, "Invalid -f|--format\n\n");
  119. goto out_usage;
  120. }
  121. } else if ((res = cmp_arg(argv, &i, "--debug", "-d", NULL)) == ARG_MATCH) {
  122. cmdargs.debug++;
  123. } else if ((res = cmp_arg(argv, &i, "--psize", "-s", NULL)) == ARG_MATCH) {
  124. cmdargs.print_sizes = 1;
  125. } else if ((res = cmp_arg(argv, &i, "--ivalext", "-e", &param)) == ARG_MATCH) {
  126. cmdargs.initvals_fn_extension = param;
  127. } else if ((res = cmp_arg(argv, &i, "--__real_infile", NULL, &param)) == ARG_MATCH) {
  128. cmdargs.real_infile_name = param;
  129. } else {
  130. fprintf(stderr, "Unrecognized argument: %s\n", argv[i]);
  131. goto out_usage;
  132. }
  133. }
  134. if (!cmdargs.real_infile_name)
  135. cmdargs.real_infile_name = infile_name;
  136. if (strcmp(cmdargs.real_infile_name, outfile_name) == 0) {
  137. fprintf(stderr, "Error: INPUT and OUTPUT filename must not be the same\n");
  138. goto out_usage;
  139. }
  140. return 0;
  141. out_usage:
  142. usage();
  143. return -1;
  144. }
  145. int open_input_file(void)
  146. {
  147. int fd;
  148. int err;
  149. if (strcmp(infile_name, "-") == 0) {
  150. /* infile == stdin */
  151. fd = STDIN_FILENO;
  152. } else {
  153. fd = open(infile_name, O_RDONLY);
  154. if (fd < 0) {
  155. fprintf(stderr, "Could not open INPUT_FILE %s\n",
  156. infile_name);
  157. return -1;
  158. }
  159. err = dup2(fd, STDIN_FILENO);
  160. if (err) {
  161. fprintf(stderr, "Could not dup INPUT_FILE %s "
  162. "to STDIN\n", infile_name);
  163. close(fd);
  164. return -1;
  165. }
  166. }
  167. infile.fd = fd;
  168. return 0;
  169. }
  170. void close_input_file(void)
  171. {
  172. if (strcmp(infile_name, "-") != 0)
  173. close(infile.fd);
  174. }