OSDN Git Service

Add MS7619SE
[uclinux-h8/uClinux-dist.git] / tools / pkg-config / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <strings.h>
4 #include <stdarg.h>
5
6 #define _GNU_SOURCE
7 #include <getopt.h>
8
9 #define MY_VERSION "0.22"
10
11
12 struct library {
13         const char *name;
14         const char *version;
15         const char *Largs;
16         const char *largs;
17         const char *Iargs;
18 };
19
20 #define LIB(n, ver, l)  { n, ver, NULL, l, NULL }
21 static const struct library all_libs[] = {
22         LIB("libxml-2.0", "2.7.2", "-lxml"),
23 };
24 #define N_LIBS  (sizeof(all_libs) / sizeof(struct library))
25
26
27 enum {
28         OPT_USAGE=300,
29         OPT_ATLEAST_PKGCONFIG_VERSION,
30         OPT_CFLAGS,
31         OPT_ERRORS_TO_STDOUT,
32         OPT_EXISTS,
33         OPT_LIBS,
34         OPT_LIBS_ONLY_L,
35         OPT_LIBS_ONLY_l,
36         OPT_PRINT_ERRORS,
37         OPT_SHORT_ERRORS,
38         OPT_VERSION,
39 #if 0
40         OPT_SILENCE_ERRORS,
41         OPT_UNINSTALLED,
42         OPT_ATLEAST_VERSION,
43         OPT_EXACT_VERSION,
44         OPT_MAX_VERSION,
45         OPT_STATIC,
46 #endif
47 };
48
49 static const struct option opts[] = {
50         { "help", 0, 0, '?' },          // These two must be first
51         { "usage", 0, 0, OPT_USAGE },
52
53         { "atleast-pkgconfig-version", 1, 0, OPT_ATLEAST_PKGCONFIG_VERSION },
54         { "cflags", 0, 0, OPT_CFLAGS },
55         { "errors-to-stdout", 0, 0, OPT_ERRORS_TO_STDOUT },
56         { "exists", 0, 0, OPT_EXISTS },
57         { "libs", 0, 0, OPT_LIBS },
58         { "libs-only-L", 0, 0, OPT_LIBS_ONLY_L },
59         { "libs-only-l", 0, 0, OPT_LIBS_ONLY_l },
60         { "print-errors", 0, 0, OPT_PRINT_ERRORS },
61         { "short-errors", 0, 0, OPT_SHORT_ERRORS },
62         { "version", 0, 0, OPT_VERSION },
63 #if 0
64         { "modversion", 0, 0, OPT_MODVERSION },
65         { "silence-errors", 0, 0, OPT_SILENCE_ERRORS },
66         { "uninstalled", 0, 0, OPT_UNINSTALLED },
67         { "atleast-version", 1, 0, OPT_ATLEAST_VERSION },
68         { "exact-version", 1, 0, OPT_EXACT_VERSION },
69         { "max-version", 1, 0, OPT_MAX_VERSION },
70         { "static", 0, 0, OPT_STATIC },
71 #endif
72         { 0, 0, 0, 0 }
73 };
74
75 static const char *min_cfg_ver = NULL;
76 static unsigned char cflags, exists, libs, l_args, L_args;
77 static unsigned char error_stdout, print_errors, short_errors;
78
79 extern void debug(const char *, ...) __attribute__ ((format(printf, 1, 2)));
80 static void msg(const char *fmt, ...) {
81         va_list ap;
82
83         va_start(ap, fmt);
84         if (error_stdout)
85                 vprintf(fmt, ap);
86         else
87                 vfprintf(stderr, fmt, ap);
88         va_end(ap);
89 }
90
91 static void usage(const char *pname) {
92         int i;
93
94         msg("Usage: %s [OPTION...]\n", pname);
95         for (i=2; opts[i].name != 0; i++)
96                 msg("  %s\n", opts[i].name);
97         msg("\nHelp options\n");
98         msg("  -?, --help\n");
99         msg("  --usage\n");
100 }
101
102 static void usage_hint(const char *pname) {
103         int i;
104         int nl = 1;
105
106         msg("Usage: %s [-?]", pname);
107         for (i=0; opts[i].name != 0; i++) {
108                 msg(" [%s", opts[i].name);
109                 if (opts[i].has_arg)
110                         msg("=ARG");
111                 msg("]");
112                 if ((i % 3) == 2) {
113                         msg("\n");
114                         nl = 0;
115                 } else
116                         nl = 1;
117         }
118         if (nl)
119                 msg("\n");
120 }
121
122
123 /* Routine to compare version strings
124  */
125 static int compare_versions(char *have, char *want) {
126         int v1, v2;
127
128         while (want != NULL && *want != '\0') {
129                 if (*have != '\0')
130                         v1 = strtol(have, &have, 10);
131                 else    v1 = 0;
132
133                 v2 = strtol(want, &want, 10);
134                 if (v1 > v2)
135                         return 0;
136                 if (v1 < v2)
137                         return -1;
138
139                 while (*have == '.') have++;
140                 while (*want == '.') want++;
141         }
142         return 0;
143 }
144
145
146 /* Routines to check out version against the desired version.
147  * Return if we're greater of equal versions, exit with an error
148  * if not.
149  */
150 static void check_version(char *want) {
151         if (compare_versions(MY_VERSION, want))
152                 exit(1);
153 }
154
155 static void process_args(int argc, char *argv[]) {
156         int c;
157         int opt_idx = 0;
158
159         while ((c = getopt_long(argc, argv, "?", opts, &opt_idx)) != -1) {
160                 switch (c) {
161                 case OPT_CFLAGS:                cflags = 1;             break;
162                 case OPT_ERRORS_TO_STDOUT:      error_stdout = 1;       break;
163                 case OPT_EXISTS:                exists = 1;             break;
164                 case OPT_LIBS:                  libs = 1;               break;
165                 case OPT_LIBS_ONLY_L:           L_args = 1;             break;
166                 case OPT_LIBS_ONLY_l:           l_args = 1;             break;
167
168                 case OPT_PRINT_ERRORS:          print_errors = 1;       break;
169                 case OPT_SHORT_ERRORS:          short_errors = 1;       break;
170
171                 case OPT_ATLEAST_PKGCONFIG_VERSION:
172                         check_version(optarg);
173                         break;
174                 case OPT_VERSION:
175                         puts(MY_VERSION);
176                         exit(0);
177                 case OPT_USAGE:
178                         usage_hint(argv[0]);
179                         exit(0);
180                 case '?':
181                         usage(argv[0]);
182                         exit(0);
183                 default:
184                         usage(argv[0]);
185                         exit(1);
186                 }
187         }
188 }
189
190
191 /* Found the required libary.
192  * produce whatever output is required.
193  */
194 static void output_lib(const struct library *l) {
195         if (cflags)
196                 if (l->Iargs != NULL)
197                         printf("%s ", l->Iargs);
198         if (libs || L_args)
199                 if (l->Largs != NULL)
200                         printf("%s ", l->Largs);
201         if (libs || l_args)
202                 if (l->largs != NULL)
203                         printf("%s ", l->largs);
204 }
205
206 /* Search for the library specified and do what is required with it.
207  */
208 static void process_library(const char *lib) {
209         int i;
210
211         for (i=0; i<N_LIBS; i++)
212                 if (strcmp(lib, all_libs[i].name) == 0)
213                         break;
214         if (i == N_LIBS) {
215                 if (print_errors) {
216                         if (short_errors)
217                                 msg("No package '%s' found\n", lib);
218                         else
219                                 msg("Package %s was not found in the pkg-config search path.\n"
220                                         "Perhaps you should add the directory containing `%s.pc'\n"
221                                         "to the PKG_CONFIG_PATH environment variable\n"
222                                         "No package '%s' found\n", lib, lib, lib);
223                 }
224                 exit(1);
225         }
226
227         output_lib(all_libs + i);
228 }
229
230
231 int main(int argc, char *argv[]) {
232         process_args(argc, argv);
233
234         while (optind < argc)
235                 process_library(argv[optind++]);
236         return 0;
237 }