Initial revision
[opensuse:hwinfo.git] / src / pnpdump / pnp-select.c
1 /* Copyright 1998 Yggdrasil Computing, Inc.
2    Written by Adam J. Richter
3
4    This file may be copied according to the terms and conditions of the
5    GNU General Public License as published by the Free Software
6    Foundation.
7 */
8
9 #include <stdio.h>
10 #include <malloc.h>
11
12 #include "resource.h"
13 #include "pnp.h"
14
15 #define ASSERT(condition)       /* as nothing */
16
17 static int
18 inc_value (struct resource *res) {
19     if (res->type != EndDep_TAG) {
20         do {
21             res->value += res->step;
22             if (res->value >= res->end) return 0;
23         } while (!((1 << (res->value & 0x1f)) & res->mask));
24         return 1;
25     }
26     else {
27         int min_priority;
28         int best_priority;
29         int best_index;
30         int i;
31         if (res->value == -1) {
32             min_priority = -1;
33         }
34         else {
35             /* Cycle through all alternatives, but try lowest
36                priority numbers first. */
37             min_priority = res->alternatives[res->value].priority;
38             for (;;) {
39                 res->value++;
40                 if (res->value >= res->end) break;
41                 if (res->alternatives[res->value].priority == min_priority) return 1;
42             }
43         }
44         best_index = -1;
45         best_priority = 4000;   /* XXX.  This assignement is unnecessary.
46                                    It only servers to get rid of a compiler
47                                    warning. */
48         /* We want to choose the numerically lowest priority, that is
49            "top" priority. */
50         for (i = 0; i < res->end; i++) {
51             if (res->alternatives[i].priority > min_priority &&
52                 (res->alternatives[i].priority < best_priority ||
53                  best_index == -1)) {
54                 best_index = i;
55                 best_priority = res->alternatives[i].priority;
56             }
57         }
58         res->value = best_index;
59         return (best_index != -1);
60     }
61 }
62
63 int
64 alloc_resources ( struct resource *res, int count,
65                   struct resource *parent_res, int parent_count) {
66     while (count > 0 && res->type != EndDep_TAG && !tag_allocable(res->type)) {
67         res++;
68         count--;
69     }
70     if (count == 0) {
71         return parent_res == NULL ? 1 :
72             alloc_resources(parent_res, parent_count, NULL, 0);
73     }                          
74     res->value = res->start - res->step;
75     while (inc_value(res)) {
76         if (res->type == EndDep_TAG) {
77             ASSERT(parent_res == NULL);
78             ASSERT(parent_count == 0);
79             if (alloc_resources(res->alternatives[res->value].resources,
80                                 res->alternatives[res->value].len,
81                                 res+1, count-1)) {
82                 return 1;
83             }
84         } else {
85             if (allocate_resource(res->type, res->value, res->size, "pnpdump")) {
86                 if (alloc_resources(res+1,count-1, parent_res, parent_count))
87                     return 1;
88                 deallocate_resource(res->type, res->value, res->size);
89             }
90         }
91     }
92     /* Resource allocation failed, reset to some sensible default value. */
93     for(res->value = res->start; res->value < res->end; res->value += res->step) {
94         if ((1 << (res->value & 0x1f)) & res->mask) break;
95     }
96     return 0;
97 }