Indentation fix, cleanup.
[AROS.git] / arch / all-pc / boot / grub2-aros / util / resolve.c
blob002bfbd720b642b03f382bd6e056adc547ebb57a
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 <config.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <ctype.h>
25 #include <errno.h>
27 #include <grub/emu/misc.h>
28 #include <grub/misc.h>
29 #include <grub/util/misc.h>
30 #include <grub/util/resolve.h>
31 #include <grub/i18n.h>
33 /* Module. */
34 struct mod_list
36 const char *name;
37 struct mod_list *next;
40 /* Dependency. */
41 struct dep_list
43 const char *name;
44 struct mod_list *list;
45 struct dep_list *next;
48 static char buf[1024];
50 static void
51 free_mod_list (struct mod_list *head)
53 while (head)
55 struct mod_list *next;
57 next = head->next;
58 free ((void *) head->name);
59 free (head);
60 head = next;
64 static void
65 free_dep_list (struct dep_list *head)
67 while (head)
69 struct dep_list *next;
71 next = head->next;
72 free ((void *) head->name);
73 free_mod_list (head->list);
74 free (head);
75 head = next;
79 /* Read the list of dependencies. */
80 static struct dep_list *
81 read_dep_list (FILE *fp)
83 struct dep_list *dep_list = 0;
85 while (fgets (buf, sizeof (buf), fp))
87 char *p;
88 struct dep_list *dep;
90 /* Get the target name. */
91 p = strchr (buf, ':');
92 if (! p)
93 grub_util_error (_("invalid line format: %s"), buf);
95 *p++ = '\0';
97 dep = xmalloc (sizeof (*dep));
98 dep->name = xstrdup (buf);
99 dep->list = 0;
101 dep->next = dep_list;
102 dep_list = dep;
104 /* Add dependencies. */
105 while (*p)
107 struct mod_list *mod;
108 char *name;
110 /* Skip whitespace. */
111 while (*p && grub_isspace (*p))
112 p++;
114 if (! *p)
115 break;
117 name = p;
119 /* Skip non-whitespace. */
120 while (*p && ! grub_isspace (*p))
121 p++;
123 *p++ = '\0';
125 mod = (struct mod_list *) xmalloc (sizeof (*mod));
126 mod->name = xstrdup (name);
127 mod->next = dep->list;
128 dep->list = mod;
132 return dep_list;
135 static char *
136 get_module_name (const char *str)
138 char *base;
139 char *ext;
141 base = strrchr (str, '/');
142 if (! base)
143 base = (char *) str;
144 else
145 base++;
147 ext = strrchr (base, '.');
148 if (ext && strcmp (ext, ".mod") == 0)
150 char *name;
152 name = xmalloc (ext - base + 1);
153 memcpy (name, base, ext - base);
154 name[ext - base] = '\0';
155 return name;
158 return xstrdup (base);
161 static char *
162 get_module_path (const char *prefix, const char *str)
164 char *dir;
165 char *base;
166 char *ext;
167 char *ret;
169 ext = strrchr (str, '.');
170 if (ext && strcmp (ext, ".mod") == 0)
171 base = xstrdup (str);
172 else
174 base = xmalloc (strlen (str) + 4 + 1);
175 sprintf (base, "%s.mod", str);
178 dir = strchr (str, '/');
179 if (dir)
180 return base;
182 ret = grub_util_get_path (prefix, base);
183 free (base);
184 return ret;
187 static void
188 add_module (const char *dir,
189 struct dep_list *dep_list,
190 struct mod_list **mod_head,
191 struct grub_util_path_list **path_head,
192 const char *name)
194 char *mod_name;
195 struct grub_util_path_list *path;
196 struct mod_list *mod;
197 struct dep_list *dep;
199 mod_name = get_module_name (name);
201 /* Check if the module has already been added. */
202 for (mod = *mod_head; mod; mod = mod->next)
203 if (strcmp (mod->name, mod_name) == 0)
205 free (mod_name);
206 return;
209 /* Resolve dependencies. */
210 for (dep = dep_list; dep; dep = dep->next)
211 if (strcmp (dep->name, mod_name) == 0)
213 for (mod = dep->list; mod; mod = mod->next)
214 add_module (dir, dep_list, mod_head, path_head, mod->name);
216 break;
219 /* Add this module. */
220 mod = (struct mod_list *) xmalloc (sizeof (*mod));
221 mod->name = mod_name;
222 mod->next = *mod_head;
223 *mod_head = mod;
225 /* Add this path. */
226 path = (struct grub_util_path_list *) xmalloc (sizeof (*path));
227 path->name = get_module_path (dir, name);
228 path->next = *path_head;
229 *path_head = path;
232 struct grub_util_path_list *
233 grub_util_resolve_dependencies (const char *prefix,
234 const char *dep_list_file,
235 char *modules[])
237 char *path;
238 FILE *fp;
239 struct dep_list *dep_list;
240 struct mod_list *mod_list = 0;
241 struct grub_util_path_list *path_list = 0;
243 path = grub_util_get_path (prefix, dep_list_file);
244 fp = grub_util_fopen (path, "r");
245 if (! fp)
246 grub_util_error (_("cannot open `%s': %s"), path, strerror (errno));
248 free (path);
249 dep_list = read_dep_list (fp);
250 fclose (fp);
252 while (*modules)
254 add_module (prefix, dep_list, &mod_list, &path_list, *modules);
255 modules++;
258 free_dep_list (dep_list);
259 free_mod_list (mod_list);
261 { /* Reverse the path_list */
262 struct grub_util_path_list *p, *prev, *next;
264 for (p = path_list, prev = NULL; p; p = next)
266 next = p->next;
267 p->next = prev;
268 prev = p;
271 return prev;