/
option.c
137 lines (121 loc) · 2.92 KB
/
option.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
* $Id: option.c,v 1.5 2001/01/14 15:37:43 james Exp $
* build-package
* (c) Copyright James Aylett
*
* build-package is released under the GPL.
*/
#include "option.h"
/*
* returns a block that has been memalloc()'ed
*/
char *read_option(struct module *am, char *name)
{
int ao=0, bo=0, co=0;
char *as=NULL, *bs=NULL, *cs=NULL;
struct module *bm=NULL;
char *result=NULL;
int size;
/* do_error("read_option(%p, %s)", am, name);*/
if (am!=NULL)
ao = find_option(am, name);
if ((bm = find_module("global"))!=NULL)
bo = find_option(bm, name);
/* else
do_error("erk! lost global!");*/
if (cli!=NULL)
co = find_option(cli, name);
/* do_error("read_option(): ao = %i, bo = %i, co = %i", ao, bo, co);*/
/* if any are 'set', then they override; otherwise, they build up */
if (ao>0)
{
bo=0;
co=0;
}
/* if (bo>0)
co=0;*/
if (co>0)
bo=0; /* cli overrides global block. This makes /much/ more sense ... */
if (ao==0 && bo==0 && co==0)
return NULL; /* couldn't find it */
as = get_option(am, ao);
bs = get_option(bm, bo);
cs = get_option(cli, co);
size = ((as==NULL)?(0):(strlen(as))) +
((bs==NULL)?(0):(strlen(bs))) +
((cs==NULL)?(0):(strlen(cs))) + 1;
result = memalloc(size);
result[0]=0;
/* cli + global + per-module. Different to absolute overrides, above, where
* cli is more important than global.
*/
if (cs!=NULL)
strcat(result, cs);
if (bs!=NULL)
strcat(result, bs);
if (as!=NULL)
strcat(result, as);
return result;
}
int find_option(struct module *module, char *name)
{
int i,k;
if (module==NULL)
return 0;
k = strlen(name);
for (i=0; i<module->num_options; i++)
{
int j=1;
char *ptr = strchr(module->options[i], '=');
if (ptr[-1]=='+')
{
j=-1;
ptr--;
}
if (k == ptr - module->options[i])
{
if (strncmp(name, module->options[i],
ptr - module->options[i])==0)
{
return j*(i+1); /* negative => += */
}
}
}
return 0;
}
char *get_option(struct module *module, int opt)
{
char *ptr;
if (opt==0 || module==NULL)
return NULL;
if (opt<0)
opt *= -1;
ptr = strchr(module->options[opt-1], '=');
return ptr+1;
}
void add_string(char ***opt, unsigned int *num, char const * option)
{
char ** temp;
unsigned int number = *num;
temp = memrealloc(*opt, (++number) * sizeof(char *));
*opt = temp;
temp[number-1] = copy_string_no_trailing_spaces(option);
*num = number;
}
char *copy_string_no_trailing_spaces(char const * str)
{
int length=strlen(str);
char *result;
while ((str[length]==' ' || str[length]==0) && length>0)
length--;
if (str[length]!=' ' && str[length]!=0)
length++;
result = memalloc((length+1) * sizeof(char));
strncpy(result, str, length);
result[length]=0;
return result;
}
void add_option(struct module *module, char const * option)
{
add_string(&module->options, &module->num_options, option);
}