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