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/>.
25 # include <sys/time.h>
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. */
34 # include <m4/m4module.h>
36 # include "m4private.h"
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);
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)
72 { NULL
, NULL
, 0, 0, 0 },
78 M4BUILTIN_HANDLER (getcwd
)
80 /* FIXME - Use gnulib module for arbitrary-length cwd. */
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);
93 M4BUILTIN_HANDLER (getenv
)
97 env
= getenv (M4ARG (1));
100 m4_shipout_string (context
, obs
, env
, SIZE_MAX
, false);
104 * setenv(NAME, VALUE, [OVERWRITE])
106 M4BUILTIN_HANDLER (setenv
)
111 if (!m4_numeric_arg (context
, m4_arg_info (argv
), M4ARG (3), M4ARGLEN (3),
116 setenv (M4ARG (1), M4ARG (2), overwrite
);
119 if (!overwrite
&& getenv (M4ARG (1)) != NULL
)
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
);
131 #endif /* HAVE_PUTENV */
132 #endif /* HAVE_SETENV */
138 M4BUILTIN_HANDLER (unsetenv
)
142 unsetenv (M4ARG (1));
143 #endif /* HAVE_UNSETENV */
149 M4BUILTIN_HANDLER (getlogin
)
156 m4_shipout_string (context
, obs
, login
, SIZE_MAX
, false);
162 M4BUILTIN_HANDLER (getpid
)
164 m4_shipout_int (obs
, getpid ());
170 M4BUILTIN_HANDLER (getppid
)
172 m4_shipout_int (obs
, getppid ());
178 M4BUILTIN_HANDLER (getpwnam
)
182 pw
= getpwnam (M4ARG (1));
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);
205 M4BUILTIN_HANDLER (getpwuid
)
210 if (!m4_numeric_arg (context
, m4_arg_info (argv
), M4ARG (1), M4ARGLEN (1),
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);
237 M4BUILTIN_HANDLER (hostname
)
241 if (gethostname (buf
, sizeof buf
) < 0)
244 m4_shipout_string (context
, obs
, buf
, SIZE_MAX
, false);
250 M4BUILTIN_HANDLER (rand
)
252 m4_shipout_int (obs
, rand ());
258 M4BUILTIN_HANDLER (srand
)
263 seed
= time (0L) * getpid ();
266 if (!m4_numeric_arg (context
, m4_arg_info (argv
), M4ARG (1),
267 M4ARGLEN (1), &seed
))
277 M4BUILTIN_HANDLER (uname
)
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);
298 M4BUILTIN_HANDLER (getuid
)
300 m4_shipout_int (obs
, getuid ());