2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
4 This file is part of Hiddtool
6 Hiddtool is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 Hiddtool is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 // #include "config.h"
33 #include <sys/types.h>
39 typedef struct _Node Node
;
67 int circularcheck
; /* Used when checking for circular dependencies */
87 # define NewList(l) (((List *)l)->prelast = (Node *)(l), \
88 ((List *)l)->last = 0, \
89 ((List *)l)->first = (Node *)&(((List *)l)->last))
91 # define AddHead(l,n) ((void)(\
92 ((Node *)n)->next = ((List *)l)->first, \
93 ((Node *)n)->prev = (Node *)&((List *)l)->first, \
94 ((List *)l)->first->prev = ((Node *)n), \
95 ((List *)l)->first = ((Node *)n)))
97 # define AddTail(l,n) ((void)(\
98 ((Node *)n)->next = (Node *)&((List *)l)->last, \
99 ((Node *)n)->prev = ((List *)l)->prelast, \
100 ((List *)l)->prelast->next = ((Node *)n), \
101 ((List *)l)->prelast = ((Node *)n) ))
103 # define Remove(n) ((void)(\
104 ((Node *)n)->prev->next = ((Node *)n)->next,\
105 ((Node *)n)->next->prev = ((Node *)n)->prev ))
107 # define GetHead(l) (void *)(((List *)l)->first->next \
108 ? ((List *)l)->first \
110 # define GetTail(l) (void *)(((List *)l)->prelast->prev \
111 ? ((List *)l)->prelast \
113 # define GetNext(n) (void *)(((Node *)n)->next->next \
114 ? ((Node *)n)->next \
116 # define GetPrev(n) (void *)(((Node *)n)->prev->prev \
117 ? ((Node *)n)->prev \
120 #define InsertBefore(n, before) \
121 ((Node *)before)->prev->next = n; \
122 ((Node *)n)->prev = ((Node *)before)->prev; \
123 ((Node *)before)->prev = n; \
124 ((Node *)n)->next = before;
126 # define ForeachNode(l,n) \
127 for (n=(void *)(((List *)(l))->first); \
128 ((Node *)(n))->next; \
129 n=(void *)(((Node *)(n))->next))
130 # define ForeachNodeSafe(l,node,nextnode) \
131 for (node=(void *)(((List *)(l))->first); \
132 ((nextnode)=(void*)((Node *)(node))->next); \
133 (node)=(void *)(nextnode))
135 #define cfree(x) if (x) free (x)
136 #define SETSTR(str,val) \
138 str = val ? xstrdup (val) : NULL
140 #define xstrdup(str) _xstrdup(str,__FILE__,__LINE__)
141 #define xmalloc(size) _xmalloc(size,__FILE__,__LINE__)
142 #define xfree(ptr) _xfree(ptr,__FILE__,__LINE__)
143 #define new(x) ((x *) xmalloc (sizeof (x)))
148 _xstrdup (const char * str
, const char * file
, int line
)
158 fprintf (stderr
, "Out of memory in %s:%d", file
, line
);
166 _xmalloc (size_t size
, const char * file
, int line
)
174 fprintf (stderr
, "Out of memory in %s:%d", file
, line
);
182 _xfree (void * ptr
, const char * file
, int line
)
187 fprintf (stderr
, "Illegal free(NULL) in %s:%d", file
, line
);
191 findnode (const List
* l
, const char * name
)
197 if (!strcmp (n
->name
, name
))
212 printf (" \"%s\"\n", n
->name
);
219 void cleanup(int exitcode
)
226 fprintf(stderr
, "Usage: hiddtool -k configfile: get list of all kernel hidds\n");
227 fprintf(stderr
, " hiddtool -d configfile: get list of all disk hidds\n");
228 fprintf(stderr
, " hiddtool -m configfile: generate metamake dependancies\n");
232 /* Returns pointer to next noblank car or NULL if end of buffer is reached */
233 char *next_not_blank(char *s
)
235 while (*s
&& isspace(*s
)) {
244 /* Returns pointer to end of word or NULL on error */
245 char *end_of_word(char *word
)
248 while (*s
&& (isalpha(*s
) || *s
== '-')) {
252 if (s
== word
) /* Target was of length 0 ? */
258 void print_deps_db(DepsDB
*db
)
262 ForeachNode(&db
->items
, item
) {
265 printf("%s :", item
->node
.name
);
267 ForeachNode(&item
->deps
, depnode
) {
268 printf(" %s", depnode
->name
);
275 static inline void freenode(Node
*n
)
277 if (NULL
!= n
->name
) {
285 void free_deps_db(DepsDB
*db
)
287 Item
*item
, *safeitem
;
289 ForeachNodeSafe(&db
->items
, item
, safeitem
) {
290 Node
*depnode
, *safedepnode
;
292 ForeachNodeSafe(&item
->deps
, depnode
, safedepnode
) {
295 freenode((Node
*)item
);
302 DepsDB
*build_deps_db(char *filename
)
308 db
= xmalloc(sizeof (*db
));
311 f
= fopen(filename
, "r");
313 fprintf(stderr
, "Could not open dependancy db file %s\n", filename
);
316 /* Read in all the dependancies */
323 char *target
, *target_end
;
326 if (NULL
== fgets(buf
, sizeof (buf
), f
))
332 /* Parse the contents in the buffer */
333 target
= s
= next_not_blank(s
);
339 fprintf(stderr
, "Malformed target at line %d in %s\n", line
, filename
);
345 /* Go to next not blanke */
346 s
= next_not_blank(s
);
348 fprintf(stderr
, "Missing colon at line %d in %s\n", line
, filename
);
354 fprintf(stderr
, "Rubbish instead of colon at line %d in %s\n", line
, filename
);
362 /* Now read all the targets dependancies */
364 /* Allocate a db item */
365 item
= xmalloc(sizeof (*item
));
366 item
->node
.name
= xstrdup(target
);
367 item
->circularcheck
= 0;
369 NewList(&item
->deps
);
371 /* Add it to the db */
372 AddTail(&db
->items
, item
);
375 /* Read all the dependencies */
381 dep
= s
= next_not_blank(s
);
385 dep_end
= s
= end_of_word(s
);
386 if (NULL
== dep_end
) {
387 fprintf(stderr
, "Malformed dependancy at line %d in %s\n", line
, filename
);
402 depnode
= xmalloc(sizeof (*depnode
));
403 depnode
->name
= xstrdup(dep
);
405 AddTail(&item
->deps
, depnode
);
407 } /* while (parse deps) */
409 } /* while (parse lines) */
412 } /* if (file opened) */
422 void free_list(List
*conf
)
426 ForeachNodeSafe(conf
, cnode
, safe
) {
427 freenode((Node
*)cnode
);
432 void print_conf(List
*conf
)
436 ForeachNode(conf
, cnode
) {
438 switch (cnode
->opt
) {
447 fprintf(stderr
, "print_conf: unknown option %d\n", cnode
->opt
);
451 printf("%s => %s\n", cnode
->node
.name
, optstr
);
455 List
*get_conf(char *filename
)
462 conf
= xmalloc(sizeof (*conf
));
465 f
= fopen(filename
, "r");
467 fprintf(stderr
, "Could not open config file %s\n", filename
);
472 char *s
, *target
, *target_end
, *opt
, *opt_end
;
475 if (NULL
== fgets(buf
, sizeof(buf
), f
))
481 target
= s
= next_not_blank(s
);
483 continue; /* Handle blank lines */
485 target_end
= s
= end_of_word(s
);
487 fprintf(stderr
, "Malformed target at line %d in %s\n", line
, filename
);
492 opt
= s
= next_not_blank(s
);
494 fprintf(stderr
, "Missing option at line %d in %s\n", line
, filename
);
499 if (opt
== target_end
) {
500 fprintf(stderr
, "Malformed option at line %d in %s\n", line
, filename
);
506 opt_end
= s
= end_of_word(s
);
507 if (NULL
== opt_end
) {
508 fprintf(stderr
, "Malformed option at line %d in %s\n", line
, filename
);
513 if (NULL
!= next_not_blank(s
)) {
514 fprintf(stderr
, "Rubbish at end of line %d in %s\n", line
, filename
);
521 cnode
= xmalloc(sizeof (*cnode
));
522 AddTail(conf
, cnode
);
523 cnode
->node
.name
= xstrdup(target
);
525 if (0 == strcmp(opt
, "kernel")) {
526 cnode
->opt
= OPT_KERNEL
;
527 } else if (0 == strcmp(opt
, "disk")) {
528 cnode
->opt
= OPT_DISK
;
530 fprintf(stderr
, "Unknown option %s at line %d in %s\n", opt
, line
, filename
);
545 int checkcircular(Item
*cur
, DepsDB
*ddb
, Item
**circ_found
)
549 if (cur
->circularcheck
) {
550 fprintf(stderr
, "Circular dependency detected:\n");
551 fprintf(stderr
, "%s depends on ", cur
->node
.name
);
555 cur
->circularcheck
= 1;
557 ForeachNode(&cur
->deps
, depnode
) {
560 dep
= (Item
*)findnode(&ddb
->items
, depnode
->node
.name
);
562 /*fprintf(stderr, "checking cirular on dependcy of %s: %s\n", cur->node.name, dep->node.name);
563 */ if (!checkcircular(dep
, ddb
, circ_found
)) {
564 if (NULL
!= *circ_found
) {
565 if (0 == strcmp(cur
->node
.name
, (*circ_found
)->node
.name
)) {
566 fprintf(stderr
, "%s\n", cur
->node
.name
);
569 fprintf(stderr
, "%s depends on ", cur
->node
.name
);
578 cur
->circularcheck
= 0;
583 int add_deps(List
*l
, Node
*dependee
, Item
*item
, DepsDB
*ddb
)
587 /*fprintf(stderr, "Looking at dep %s\n", item->node.name);
589 if (!checkcircular(item
, ddb
, &circ_found
))
592 /* Check if this item allredy exists in the list */
593 n
= findnode(l
, item
->node
.name
);
595 /*fprintf(stderr, "Allready existed in list\n");
599 n
= xmalloc(sizeof (*n
));
600 n
->name
= xstrdup(item
->node
.name
);
602 if (NULL
!= dependee
) {
604 /* Insert before the dependee */
605 /*fprintf(stderr, "Inserted before dependee %s\n", dependee->name);
606 */ InsertBefore(n
, dependee
);
609 /*fprintf(stderr, "Added at end of list\n");
613 /* Go through everything we depend on and add it to the list */
614 ForeachNode(&item
->deps
, depnode
) {
616 /*fprintf(stderr, "Looking at dep in list: %s\n", depnode->node.name);
617 */ /* Find the item in the deps DB */
618 dep
= (Item
*)findnode(&ddb
->items
, depnode
->node
.name
);
620 /*fprintf(stderr, "Found dep for %s: %s\n", depnode->node.name, dep->node.name);
621 */ /* This dependany has more under-dependancies. Check it out */
622 if (!add_deps(l
, n
, dep
, ddb
))
625 fprintf(stderr
, "Non existing dependancy: %s\n", depnode
->node
.name
);
635 List
*do_deps(List
*conf
, DepsDB
*ddb
, int opt
)
641 deps
= xmalloc(sizeof (*deps
));
644 /* Go through all entries in the conf list */
645 ForeachNode(conf
, cnode
) {
647 if (opt
!= cnode
->opt
)
650 /* Find in the deps db */
651 item
= (Item
*)findnode(&ddb
->items
, cnode
->node
.name
);
653 fprintf(stderr
, "Target %s could not be found in dependancy db\n", cnode
->node
.name
);
658 if (!add_deps(deps
, NULL
, item
, ddb
)) {
672 void print_deps(List
*deps
, const char *pre
)
676 ForeachNode(deps
, dnode
) {
677 printf("%s%s ", pre
, dnode
->name
);
681 #define get_kernel_deps(conf, ddb) \
682 do_deps(conf, ddb, OPT_KERNEL)
684 List
*get_disk_deps(List
*conf
, DepsDB
*ddb
, List
*supkdeps
)
688 /* First get the disk deps */
689 ddeps
= do_deps(conf
, ddb
, OPT_DISK
);
692 if (NULL
== supkdeps
) {
693 kdeps
= do_deps(conf
, ddb
, OPT_KERNEL
);
698 Node
*ddep
, *ddepsafe
;
699 /* Go through all disk deps and see if it exists among the kernel deps. If so, remove it */
700 ForeachNodeSafe(ddeps
, ddep
, ddepsafe
) {
703 kdep
= findnode(kdeps
, ddep
->name
);
705 /* Allready in kernel. Remove from disk */
712 if (NULL
== supkdeps
)
713 free_list(kdeps
); /* Dependancies were gotten incide here */
724 void print_meta_targets(List
*deps
, const char *text
)
726 printf("#MM hidd-%s : ", text
);
727 print_deps(deps
, "hidd-");
730 printf("hidd-%s : hidd-%s-local\n",text
, text
);
731 printf("\t@(NOP)\n");
734 int do_metamake(List
*conf
, DepsDB
*ddb
)
739 kdeps
= get_kernel_deps(conf
, ddb
);
743 ddeps
= get_disk_deps(conf
, ddb
, kdeps
);
746 print_meta_targets(kdeps
, "kernel");
748 print_meta_targets(ddeps
, "disk");
761 #define DEPSFILE "./hidds.dep"
764 #define DO_KERNEL 0x02
765 #define DO_METAMAKE 0x04
769 int main(int argc
, char *argv
[])
780 c
= getopt(argc
, argv
, "kdm");
793 action
|= DO_METAMAKE
;
802 if (optind
+ 1 != argc
)
805 configfile
= argv
[optind
];
809 /* We used flags to get the options. This way we easily catch the case where
810 the user has passed more than one option.
812 if (action
!= DO_KERNEL
&& action
!= DO_DISK
&& action
!= DO_METAMAKE
)
816 ddb
= build_deps_db(DEPSFILE
);
820 // print_deps_db(ddb);
822 conf
= get_conf(configfile
);
827 deps
= get_disk_deps(conf
, ddb
, NULL
);
831 deps
= get_kernel_deps(conf
, ddb
);
836 if (!do_metamake(conf
, ddb
)) {
844 /* Print and free stuff from DO_DISK and DO_KERNEL */
845 if (action
== DO_DISK
|| action
== DO_KERNEL
) {
847 print_deps(deps
, "");