Make gnulib a git submodule.
[m4.git] / modules / stdlib.c
blob3fce71f813ddd490c69a266e483481137d0b51ed
1 /* GNU m4 -- A simple macro processor
2 Copyright (C) 1999, 2000, 2001, 2006, 2007, 2008, 2009 Free
3 Software Foundation, Inc.
5 This file is part of GNU M4.
7 GNU M4 is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU M4 is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
23 #include <pwd.h>
24 #if TM_IN_SYS_TIME
25 # include <sys/time.h>
26 #else
27 # include <time.h>
28 #endif
29 #include <sys/utsname.h>
31 /* Build using only the exported interfaces, unless NDEBUG is set, in
32 which case use private symbols to speed things up as much as possible. */
33 #ifndef NDEBUG
34 # include <m4/m4module.h>
35 #else
36 # include "m4private.h"
37 #endif
39 /* Rename exported symbols for dlpreload()ing. */
40 #define m4_builtin_table stdlib_LTX_m4_builtin_table
42 /* function macros blind side minargs maxargs */
43 #define builtin_functions \
44 BUILTIN (getcwd, false, false, false, 0, 0 ) \
45 BUILTIN (getenv, false, true, false, 1, 1 ) \
46 BUILTIN (getlogin, false, false, false, 0, 0 ) \
47 BUILTIN (getpid, false, false, false, 0, 0 ) \
48 BUILTIN (getppid, false, false, false, 0, 0 ) \
49 BUILTIN (getuid, false, false, false, 0, 0 ) \
50 BUILTIN (getpwnam, false, true, false, 1, 1 ) \
51 BUILTIN (getpwuid, false, true, false, 1, 1 ) \
52 BUILTIN (hostname, false, false, false, 0, 0 ) \
53 BUILTIN (rand, false, false, false, 0, 0 ) \
54 BUILTIN (srand, false, false, false, 0, 1 ) \
55 BUILTIN (setenv, false, true, false, 2, 3 ) \
56 BUILTIN (unsetenv, false, true, false, 1, 1 ) \
57 BUILTIN (uname, false, false, false, 0, 0 ) \
60 #define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler);
61 builtin_functions
62 #undef BUILTIN
64 const m4_builtin m4_builtin_table[] =
66 #define BUILTIN(handler, macros, blind, side, min, max) \
67 M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
69 builtin_functions
70 #undef BUILTIN
72 { NULL, NULL, 0, 0, 0 },
75 /**
76 * getcwd()
77 **/
78 M4BUILTIN_HANDLER (getcwd)
80 /* FIXME - Use gnulib module for arbitrary-length cwd. */
81 char buf[1024];
82 char *bp;
84 bp = getcwd (buf, sizeof buf);
86 if (bp != NULL) /* in case of error return null string */
87 m4_shipout_string (context, obs, buf, SIZE_MAX, false);
90 /**
91 * getenv(NAME)
92 **/
93 M4BUILTIN_HANDLER (getenv)
95 char *env;
97 env = getenv (M4ARG (1));
99 if (env != NULL)
100 m4_shipout_string (context, obs, env, SIZE_MAX, false);
104 * setenv(NAME, VALUE, [OVERWRITE])
106 M4BUILTIN_HANDLER (setenv)
108 int overwrite = 1;
110 if (argc >= 4)
111 if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (3), M4ARGLEN (3),
112 &overwrite))
113 return;
115 #if HAVE_SETENV
116 setenv (M4ARG (1), M4ARG (2), overwrite);
117 #else
118 #if HAVE_PUTENV
119 if (!overwrite && getenv (M4ARG (1)) != NULL)
120 return;
122 assert (obstack_object_size (obs) == 0);
123 obstack_grow (obs, M4ARG (1), M4ARGLEN (1));
124 obstack_1grow (obs, '=');
125 obstack_grow0 (obs, M4ARG (2), M4ARGLEN (2));
128 char *env = (char *) obstack_finish (obs);
129 putenv (env);
131 #endif /* HAVE_PUTENV */
132 #endif /* HAVE_SETENV */
136 * unsetenv(NAME)
138 M4BUILTIN_HANDLER (unsetenv)
141 #if HAVE_UNSETENV
142 unsetenv (M4ARG (1));
143 #endif /* HAVE_UNSETENV */
147 * getlogin()
149 M4BUILTIN_HANDLER (getlogin)
151 char *login;
153 login = getlogin ();
155 if (login != NULL)
156 m4_shipout_string (context, obs, login, SIZE_MAX, false);
160 * getpid()
162 M4BUILTIN_HANDLER (getpid)
164 m4_shipout_int (obs, getpid ());
168 * getppid()
170 M4BUILTIN_HANDLER (getppid)
172 m4_shipout_int (obs, getppid ());
176 * getpwnam(NAME)
178 M4BUILTIN_HANDLER (getpwnam)
180 struct passwd *pw;
182 pw = getpwnam (M4ARG (1));
184 if (pw != NULL)
186 m4_shipout_string (context, obs, pw->pw_name, SIZE_MAX, true);
187 obstack_1grow (obs, ',');
188 m4_shipout_string (context, obs, pw->pw_passwd, SIZE_MAX, true);
189 obstack_1grow (obs, ',');
190 m4_shipout_int (obs, pw->pw_uid);
191 obstack_1grow (obs, ',');
192 m4_shipout_int (obs, pw->pw_gid);
193 obstack_1grow (obs, ',');
194 m4_shipout_string (context, obs, pw->pw_gecos, SIZE_MAX, true);
195 obstack_1grow (obs, ',');
196 m4_shipout_string (context, obs, pw->pw_dir, SIZE_MAX, true);
197 obstack_1grow (obs, ',');
198 m4_shipout_string (context, obs, pw->pw_shell, SIZE_MAX, true);
203 * getpwuid(UID)
205 M4BUILTIN_HANDLER (getpwuid)
207 struct passwd *pw;
208 int uid;
210 if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1),
211 &uid))
212 return;
214 pw = getpwuid (uid);
216 if (pw != NULL)
218 m4_shipout_string (context, obs, pw->pw_name, SIZE_MAX, true);
219 obstack_1grow (obs, ',');
220 m4_shipout_string (context, obs, pw->pw_passwd, SIZE_MAX, true);
221 obstack_1grow (obs, ',');
222 m4_shipout_int (obs, pw->pw_uid);
223 obstack_1grow (obs, ',');
224 m4_shipout_int (obs, pw->pw_gid);
225 obstack_1grow (obs, ',');
226 m4_shipout_string (context, obs, pw->pw_gecos, SIZE_MAX, true);
227 obstack_1grow (obs, ',');
228 m4_shipout_string (context, obs, pw->pw_dir, SIZE_MAX, true);
229 obstack_1grow (obs, ',');
230 m4_shipout_string (context, obs, pw->pw_shell, SIZE_MAX, true);
235 * hostname()
237 M4BUILTIN_HANDLER (hostname)
239 char buf[1024];
241 if (gethostname (buf, sizeof buf) < 0)
242 return;
244 m4_shipout_string (context, obs, buf, SIZE_MAX, false);
248 * rand()
250 M4BUILTIN_HANDLER (rand)
252 m4_shipout_int (obs, rand ());
256 * srand()
258 M4BUILTIN_HANDLER (srand)
260 int seed;
262 if (argc == 1)
263 seed = time (0L) * getpid ();
264 else
266 if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1),
267 M4ARGLEN (1), &seed))
268 return;
271 srand (seed);
275 * uname()
277 M4BUILTIN_HANDLER (uname)
279 struct utsname ut;
281 if (uname (&ut) == 0)
283 m4_shipout_string (context, obs, ut.sysname, SIZE_MAX, true);
284 obstack_1grow (obs, ',');
285 m4_shipout_string (context, obs, ut.nodename, SIZE_MAX, true);
286 obstack_1grow (obs, ',');
287 m4_shipout_string (context, obs, ut.release, SIZE_MAX, true);
288 obstack_1grow (obs, ',');
289 m4_shipout_string (context, obs, ut.version, SIZE_MAX, true);
290 obstack_1grow (obs, ',');
291 m4_shipout_string (context, obs, ut.machine, SIZE_MAX, true);
296 * getuid()
298 M4BUILTIN_HANDLER (getuid)
300 m4_shipout_int (obs, getuid ());