chiark / gitweb /
codec/{base32,hex}.h: Include `codec.h'.
[mLib] / sys / env.c
CommitLineData
e19206c2 1/* -*-c-*-
e19206c2 2 *
3 * Fiddling with environment variables
4 *
5 * (c) 1999 Straylight/Edgeware
6 */
7
d4efbcd9 8/*----- Licensing notice --------------------------------------------------*
e19206c2 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.
d4efbcd9 16 *
e19206c2 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.
d4efbcd9 21 *
e19206c2 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
e19206c2 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
39typedef 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
58char *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
81void 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] == '=') {
20eb516f 90 q = x_alloc(t->t.a, eq + 1);
e19206c2 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) {
20eb516f 103 x_free(t->t.a, v->v);
e19206c2 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)
20eb516f 110 x_free(t->t.a, v->v);
111 v->v = x_strdup(t->t.a, value);
e19206c2 112 }
113
114 /* --- Tidying --- */
115
116 if (q)
20eb516f 117 xfree(q);
e19206c2 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
132void 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
151char **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++;
f41204b3 164 sz += SYM_LEN(v) + strlen(v->v) + 2;
e19206c2 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
196void 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; )
20eb516f 202 x_free(t->t.a, v->v);
e19206c2 203 sym_destroy(t);
204}
205
206/*----- That's all, folks -------------------------------------------------*/