struct/dstr-putf.c: Remove apparently redundant inclusion of <math.h>.
[mLib] / sys / env.c
1 /* -*-c-*-
2 *
3 * Fiddling with environment variables
4 *
5 * (c) 1999 Straylight/Edgeware
6 */
7
8 /*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of the mLib utilities library.
11 *
12 * mLib is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * mLib is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with mLib; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * MA 02111-1307, USA.
26 */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "alloc.h"
35 #include "sym.h"
36
37 /*----- Data structures ---------------------------------------------------*/
38
39 typedef struct var {
40 sym_base _base;
41 char *v;
42 } var;
43
44 /*----- Main code ---------------------------------------------------------*/
45
46 /* --- @env_get@ --- *
47 *
48 * Arguments: @sym_table *t@ = pointer to a symbol table
49 * @const char *name@ = pointer to variable name to look up
50 *
51 * Returns: Pointer to corresponding value string, or null.
52 *
53 * Use: Looks up an environment variable in the table and returns its
54 * value. If the variable can't be found, a null pointer is
55 * returned.
56 */
57
58 char *env_get(sym_table *t, const char *name)
59 {
60 var *e = sym_find(t, name, -1, 0, 0);
61 return (e ? e->v : 0);
62 }
63
64 /* --- @env_put@ --- *
65 *
66 * Arguments: @sym_table *t@ = pointer to a symbol table
67 * @const char *name@ = pointer to variable name to set
68 * @const char *value@ = pointer to value string to assign
69 *
70 * Returns: ---
71 *
72 * Use: Assigns a value to a variable. If the @name@ contains an
73 * equals character, then it's assumed to be of the form
74 * `VAR=VALUE' and @value@ argument is ignored. Otherwise, if
75 * @value@ is null, the variable is deleted. Finally, the
76 * normal case: @name@ is a plain name, and @value@ is a normal
77 * string causes the variable to be assigned the value in the
78 * way you'd expect.
79 */
80
81 void env_put(sym_table *t, const char *name, const char *value)
82 {
83 char *q = 0;
84
85 /* --- Sort out the mess with `NAME=VALUE' forms --- */
86
87 {
88 size_t eq = strcspn(name, "=");
89 if (name[eq] == '=') {
90 q = x_alloc(t->t.a, eq + 1);
91 memcpy(q, name, eq);
92 q[eq] = 0;
93 value = name + eq + 1;
94 name = q;
95 }
96 }
97
98 /* --- Read the current value --- */
99
100 if (!value) {
101 var *v;
102 if ((v = sym_find(t, name, -1, 0, 0)) != 0) {
103 x_free(t->t.a, v->v);
104 sym_remove(t, v);
105 }
106 } else {
107 unsigned found;
108 var *v = sym_find(t, name, -1, sizeof(*v), &found);
109 if (found)
110 x_free(t->t.a, v->v);
111 v->v = x_strdup(t->t.a, value);
112 }
113
114 /* --- Tidying --- */
115
116 if (q)
117 xfree(q);
118 }
119
120 /* --- @env_import@ --- *
121 *
122 * Arguments: @sym_table *t@ = pointer to a symbol table
123 * @char **env@ = pointer to an environment list
124 *
125 * Returns: ---
126 *
127 * Use: Inserts all of the environment variables listed into a symbol
128 * table for rapid access. Equivalent to a lot of calls to
129 * @env_put@.
130 */
131
132 void env_import(sym_table *t, char **env)
133 {
134 while (*env) {
135 env_put(t, *env, 0);
136 env++;
137 }
138 }
139
140 /* --- @env_export@ --- *
141 *
142 * Arguments: @sym_table *t@ = pointer to a symbol table
143 *
144 * Returns: A big environment list.
145 *
146 * Use: Extracts an environment table from a symbol table
147 * representation of an environment. The table and all of the
148 * strings are in one big block allocated from the heap.
149 */
150
151 char **env_export(sym_table *t)
152 {
153 size_t n = 1;
154 size_t sz = 0;
155 sym_iter i;
156 var *v;
157 char **env;
158 char *p, **pp;
159
160 /* --- Work out sizes for everything --- */
161
162 for (sym_mkiter(&i, t); (v = sym_next(&i)) != 0; ) {
163 n++;
164 sz += SYM_LEN(v) + strlen(v->v) + 2;
165 }
166
167 /* --- Allocate the big chunk of memory --- */
168
169 env = pp = xmalloc(n * sizeof(char *) + sz);
170 p = (char *)(env + n);
171
172 /* --- Dump the output in the big chunk of memory --- */
173
174 for (sym_mkiter(&i, t); (v = sym_next(&i)) != 0; ) {
175 const char *name = SYM_NAME(v);
176 size_t nlen = strlen(name), vlen = strlen(v->v);
177 *pp++ = p;
178 memcpy(p, name, nlen); p += nlen;
179 *p++ = '=';
180 memcpy(p, v->v, vlen); p += vlen;
181 *p++ = 0;
182 }
183 *pp++ = 0;
184 return (env);
185 }
186
187 /* --- @env_destroy@ --- *
188 *
189 * Arguments: @sym_table *t@ = pointer to symbol table
190 *
191 * Returns: ---
192 *
193 * Use: Destroys all the variables in the symbol table.
194 */
195
196 void env_destroy(sym_table *t)
197 {
198 sym_iter i;
199 var *v;
200
201 for (sym_mkiter(&i, t); (v = sym_next(&i)) != 0; )
202 x_free(t->t.a, v->v);
203 sym_destroy(t);
204 }
205
206 /*----- That's all, folks -------------------------------------------------*/