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/>.
25 #define SYMTAB_SIZE 509
40 static char buf
[BUF_SIZE
];
41 static struct symbol
*symtab
[SYMTAB_SIZE
];
44 err (const char *fmt
, ...)
48 fprintf (stderr
, "genmoddep: error: ");
51 vfprintf (stderr
, fmt
, ap
);
65 err ("out of memory");
71 xstrdup (const char *str
)
77 s
= (char *) xmalloc (len
+ 1);
78 memcpy (s
, str
, len
+ 1);
88 end
= strlen (str
) - 1;
97 symbol_hash (const char *s
)
102 key
= key
* 65599 + *s
++;
104 return (key
+ (key
>> 5)) % SYMTAB_SIZE
;
107 static struct symbol
*
108 get_symbol (const char *name
)
113 k
= symbol_hash (name
);
114 for (sym
= symtab
[k
]; sym
; sym
= sym
->next
)
115 if (strcmp (sym
->name
, name
) == 0)
122 add_symbol (const char *name
, const char *mod
)
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
];
144 for (i
= 0; i
< SYMTAB_SIZE
; i
++)
146 struct symbol
*p
, *q
;
152 free ((void *) p
->name
);
153 free ((void *) p
->mod
);
161 read_defined_symbols (FILE *fp
)
163 while (fgets (buf
, sizeof (buf
), fp
))
168 err ("empty symbol name: %s", buf
);
170 p
= strchr (buf
, ' ');
172 err ("invalid line format: %s", buf
);
177 err ("empty module name: %s", buf
);
187 add_module (struct module
**head
, const char *name
)
191 for (mod
= *head
; mod
; mod
= mod
->next
)
192 if (strcmp (mod
->name
, name
) == 0)
195 mod
= (struct module
*) xmalloc (sizeof (*mod
));
196 mod
->name
= xstrdup (name
);
203 free_modules (struct module
*head
)
210 free ((void *) head
->name
);
217 find_dependencies (FILE *fp
)
220 struct module
*mod_list
= 0;
223 if (! fgets (buf
, sizeof (buf
), fp
) || buf
[0] == '\n' || buf
[0] == '\0')
224 err ("no module name");
227 mod_name
= xstrdup (buf
);
229 while (fgets (buf
, sizeof (buf
), fp
))
234 sym
= get_symbol (buf
);
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
);
249 free_modules (mod_list
);
253 main (int argc
, char *argv
[])
257 /* First, get defined symbols. */
258 read_defined_symbols (stdin
);
260 /* Second, find the dependencies. */
261 for (i
= 1; i
< argc
; i
++)
265 fp
= fopen (argv
[i
], "r");
267 err ("cannot open %s", argv
[i
]);
269 find_dependencies (fp
);
274 /* Last, free memory. */