make the linux-ppc packags be in synch with other platforms
[tangerine.git] / arch / common / boot / grub2 / util / genmoddep.c
blobe2620a81f2c7de7445097824a2ef0eb25a73f3eb
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2002,2007 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
24 #define BUF_SIZE 1024
25 #define SYMTAB_SIZE 509
27 struct symbol
29 const char *name;
30 const char *mod;
31 struct symbol *next;
34 struct module
36 const char *name;
37 struct module *next;
40 static char buf[BUF_SIZE];
41 static struct symbol *symtab[SYMTAB_SIZE];
43 static void
44 err (const char *fmt, ...)
46 va_list ap;
48 fprintf (stderr, "genmoddep: error: ");
50 va_start (ap, fmt);
51 vfprintf (stderr, fmt, ap);
52 va_end (ap);
54 fputc ('\n', stderr);
55 exit (1);
58 static void *
59 xmalloc (size_t size)
61 void *p;
63 p = malloc (size);
64 if (! p)
65 err ("out of memory");
67 return p;
70 static char *
71 xstrdup (const char *str)
73 char *s;
74 size_t len;
76 len = strlen (str);
77 s = (char *) xmalloc (len + 1);
78 memcpy (s, str, len + 1);
80 return s;
83 static void
84 chomp (char *str)
86 int end;
88 end = strlen (str) - 1;
89 if (end < 0)
90 err ("empty string");
92 if (str[end] == '\n')
93 str[end] = '\0';
96 static unsigned
97 symbol_hash (const char *s)
99 unsigned key = 0;
101 while (*s)
102 key = key * 65599 + *s++;
104 return (key + (key >> 5)) % SYMTAB_SIZE;
107 static struct symbol *
108 get_symbol (const char *name)
110 unsigned k;
111 struct symbol *sym;
113 k = symbol_hash (name);
114 for (sym = symtab[k]; sym; sym = sym->next)
115 if (strcmp (sym->name, name) == 0)
116 return sym;
118 return 0;
121 static void
122 add_symbol (const char *name, const char *mod)
124 unsigned k;
125 struct symbol *sym;
127 if (get_symbol (name))
128 err ("duplicated symbol: %s", name);
130 sym = (struct symbol *) xmalloc (sizeof (*sym));
131 sym->name = xstrdup (name);
132 sym->mod = xstrdup (mod);
134 k = symbol_hash (name);
135 sym->next = symtab[k];
136 symtab[k] = sym;
139 static void
140 free_symbols (void)
142 int i;
144 for (i = 0; i < SYMTAB_SIZE; i++)
146 struct symbol *p, *q;
148 p = symtab[i];
149 while (p)
151 q = p->next;
152 free ((void *) p->name);
153 free ((void *) p->mod);
154 free (p);
155 p = q;
160 static void
161 read_defined_symbols (FILE *fp)
163 while (fgets (buf, sizeof (buf), fp))
165 char *p;
167 if (! *buf)
168 err ("empty symbol name: %s", buf);
170 p = strchr (buf, ' ');
171 if (! p)
172 err ("invalid line format: %s", buf);
174 p++;
176 if (! *p)
177 err ("empty module name: %s", buf);
179 *(p - 1) = '\0';
180 chomp (p);
182 add_symbol (buf, p);
186 static void
187 add_module (struct module **head, const char *name)
189 struct module *mod;
191 for (mod = *head; mod; mod = mod->next)
192 if (strcmp (mod->name, name) == 0)
193 return;
195 mod = (struct module *) xmalloc (sizeof (*mod));
196 mod->name = xstrdup (name);
198 mod->next = *head;
199 *head = mod;
202 static void
203 free_modules (struct module *head)
205 struct module *next;
207 while (head)
209 next = head->next;
210 free ((void *) head->name);
211 free (head);
212 head = next;
216 static void
217 find_dependencies (FILE *fp)
219 char *mod_name;
220 struct module *mod_list = 0;
221 struct module *mod;
223 if (! fgets (buf, sizeof (buf), fp) || buf[0] == '\n' || buf[0] == '\0')
224 err ("no module name");
226 chomp (buf);
227 mod_name = xstrdup (buf);
229 while (fgets (buf, sizeof (buf), fp))
231 struct symbol *sym;
233 chomp (buf);
234 sym = get_symbol (buf);
235 if (! sym)
236 err ("%s in %s is not defined", buf, mod_name);
238 add_module (&mod_list, sym->mod);
241 printf ("%s:", mod_name);
243 for (mod = mod_list; mod; mod = mod->next)
244 if (strcmp (mod->name, "kernel") != 0)
245 printf (" %s", mod->name);
247 putchar ('\n');
249 free_modules (mod_list);
253 main (int argc, char *argv[])
255 int i;
257 /* First, get defined symbols. */
258 read_defined_symbols (stdin);
260 /* Second, find the dependencies. */
261 for (i = 1; i < argc; i++)
263 FILE *fp;
265 fp = fopen (argv[i], "r");
266 if (! fp)
267 err ("cannot open %s", argv[i]);
269 find_dependencies (fp);
271 fclose (fp);
274 /* Last, free memory. */
275 free_symbols ();
277 return 0;