asm: Cleanup makefile.
[b43-tools.git] / assembler / args.c
1 /*
2  *   Copyright (C) 2006-2007  Michael Buesch <mb@bu3sch.de>
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
14 #include "args.h"
15 #include "main.h"
16 #include "util.h"
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23
24
25 int _debug;
26
27 #define ARG_MATCH               0
28 #define ARG_NOMATCH             1
29 #define ARG_ERROR               -1
30
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
40         arg = argv[*pos];
41         next_arg = argv[*pos + 1];
42         arg_len = strlen(arg);
43         template_len = strlen(template);
44
45         if (param) {
46                 /* Maybe we have a merged parameter here.
47                  * A merged parameter is "-pfoobar" for example.
48                  */
49                 if (allow_merged && arg_len > template_len) {
50                         if (memcmp(arg, template, template_len) == 0) {
51                                 *param = arg + template_len;
52                                 return ARG_MATCH;
53                         }
54                         return ARG_NOMATCH;
55                 } else if (arg_len != template_len)
56                         return ARG_NOMATCH;
57                 *param = next_arg;
58         }
59         if (strcmp(arg, template) == 0) {
60                 if (param) {
61                         /* Skip the parameter on the next iteration. */
62                         (*pos)++;
63                         if (*param == 0) {
64                                 fprintf(stderr, "%s needs a parameter\n", arg);
65                                 return ARG_ERROR;
66                         }
67                 }
68                 return ARG_MATCH;
69         }
70
71         return ARG_NOMATCH;
72 }
73
74 /* Simple and lean command line argument parsing. */
75 static int cmp_arg(char **argv, int *pos,
76                    const char *long_template,
77                    const char *short_template,
78                    char **param)
79 {
80         int err;
81
82         if (long_template) {
83                 err = do_cmp_arg(argv, pos, long_template, 0, param);
84                 if (err == ARG_MATCH || err == ARG_ERROR)
85                         return err;
86         }
87         err = ARG_NOMATCH;
88         if (short_template)
89                 err = do_cmp_arg(argv, pos, short_template, 1, param);
90         return err;
91 }
92
93 static void usage(int argc, char **argv)
94 {
95         fprintf(stderr, "Usage: %s INPUT_FILE OUTPUT_FILE [OPTIONS]\n", argv[0]);
96         fprintf(stderr, "  -h|--help           Print this help\n");
97         fprintf(stderr, "  -d|--debug          Print verbose debugging info\n");
98         fprintf(stderr, "                      Repeat for more verbose debugging\n");
99 }
100
101 int parse_args(int argc, char **argv)
102 {
103         int i;
104         int res;
105
106         if (argc < 3)
107                 goto out_usage;
108         infile_name = argv[1];
109         outfile_name = argv[2];
110
111         for (i = 3; i < argc; i++) {
112                 if ((res = cmp_arg(argv, &i, "--help", "-h", 0)) == ARG_MATCH) {
113                         usage(argc, argv);
114                         return 1;
115                 } else if ((res = cmp_arg(argv, &i, "--debug", "-d", 0)) == ARG_MATCH) {
116                         _debug++;
117                 } else {
118                         fprintf(stderr, "Unrecognized argument: %s\n", argv[i]);
119                         goto out_usage;
120                 }
121         }
122         return 0;
123 out_usage:
124         usage(argc, argv);
125         return -1;
126 }
127
128 int open_input_file(void)
129 {
130         int fd;
131         int err;
132
133         if (strcmp(infile_name, "-") == 0) {
134                 /* infile == stdin */
135                 fd = STDIN_FILENO;
136         } else {
137                 fd = open(infile_name, O_RDONLY);
138                 if (fd < 0) {
139                         fprintf(stderr, "Could not open INPUT_FILE %s\n",
140                                 infile_name);
141                         return -1;
142                 }
143                 err = dup2(fd, STDIN_FILENO);
144                 if (err) {
145                         fprintf(stderr, "Could not dup INPUT_FILE %s "
146                                 "to STDIN\n", infile_name);
147                         close(fd);
148                         return -1;
149                 }
150         }
151         infile.fd = fd;
152
153         return 0;
154 }
155
156 void close_input_file(void)
157 {
158         if (strcmp(infile_name, "-") != 0)
159                 close(infile.fd);
160 }