orphan
[debian/elilo] / vars.c
1 /*
2  *  Copyright (C) 2001-2003 Hewlett-Packard Co.
3  *      Contributed by Stephane Eranian <eranian@hpl.hp.com>
4  *
5  *  Copyright (C) 2001 Silicon Graphics, Inc.
6  *      Contributed by Brent Casavant <bcasavan@sgi.com>
7  *
8  * This file is part of the ELILO, the EFI Linux boot loader.
9  *
10  *  ELILO is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  ELILO is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with ELILO; see the file COPYING.  If not, write to the Free
22  *  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23  *  02111-1307, USA.
24  *
25  * Please check out the elilo.txt for complete documentation on how
26  * to use this program.
27  */
28 #include <efi.h>
29 #include <efilib.h>
30
31 /*
32  * A variable name is 1 character long and case sensitive. So 
33  * we actually have 52 (26*2) possible variables.
34  */
35 #define MAX_VARIABLES           (26<<1)
36 #define MAX_VARIABLE_LENGTH     128
37 #define VAR_IDX(a)              (((a) >= 'a' && (a) <= 'z') ? 26-'a'+(a) : (a)-'A')
38 #define IDX_VAR(i)              ((i) < 26 ? 'A'+(i) : 'a'+ ((i)-26))
39
40 typedef struct {
41         CHAR16  value[MAX_VARIABLE_LENGTH];
42 } elilo_var_t;
43
44 static elilo_var_t vars[MAX_VARIABLES]; /* set of variables */
45
46 INTN
47 set_var(CHAR16 v, CHAR16 *value)
48 {
49         /* invalid variable name */
50         if (v < 'A' || (v > 'Z' && v < 'a') || v > 'z') return -1;
51
52         StrCpy(vars[VAR_IDX(v)].value, value);
53         return 0;
54 }
55
56 CHAR16 *
57 get_var(CHAR16 v)
58 {
59         /* invalid variable name */
60         if (v < L'A' || (v > L'Z' && v < L'a') || v > L'z') return NULL;
61
62         return vars[VAR_IDX(v)].value;
63 }
64
65
66 VOID
67 print_vars(VOID)
68 {
69         INTN i;
70         UINTN cnt = 0;
71
72         for(i=0; i < MAX_VARIABLES; i++) {
73                 if (vars[i].value[0]) {
74                         cnt++;
75                         Print(L"%c = \"%s\"\n", IDX_VAR(i), vars[i].value);
76                 }
77         }
78         if (cnt == 0) Print(L"no variable defined\n");
79 }
80
81
82 INTN
83 subst_vars(CHAR16 *in, CHAR16 *out, INTN maxlen)
84 {
85         /* 
86          * we cannot use \\ for the despecialization character because
87          * it is also used as a path separator in EFI.
88          */
89 #define DSPEC_CHAR      L'&'
90         INTN i, l, j, cnt;
91         INTN m = 0, d = 0;
92         CHAR16 *val;
93
94         if (in == NULL || out == NULL || maxlen <= 1) return -1;
95
96         l = StrLen(in);
97
98         maxlen--;
99
100         for (i=0, j=0;i < l; i++) {
101                 cnt = 1;
102                 val = in+i;
103
104                 if (*val == DSPEC_CHAR  && d == 0) {
105                         d = 1; 
106                         continue;
107                 }
108                 if(m == 1) {
109                     m = 0;
110                     val = get_var(*val);
111
112                     if (val == NULL) continue;
113
114                     cnt = StrLen(val);
115
116                 } else if (*val == L'%' && d == 0) {
117                         m = 1;
118                         continue;
119                 }
120                 d = 0;
121                 while (j < maxlen && cnt) {
122                         out[j++] = *val++;
123                         cnt--;
124                 }
125                 if (j == maxlen) break;
126         }
127         out[j] = CHAR_NULL;
128
129         return 0;
130 }