1 /* GNU m4 -- A simple macro processor
2 Copyright (C) 1999-2001, 2006-2010, 2013-2014 Free Software
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 /* function macros blind side minargs maxargs */
40 #define builtin_functions \
41 BUILTIN (getcwd, false, false, false, 0, 0 ) \
42 BUILTIN (getenv, false, true, false, 1, 1 ) \
43 BUILTIN (getlogin, false, false, false, 0, 0 ) \
44 BUILTIN (getpid, false, false, false, 0, 0 ) \
45 BUILTIN (getppid, false, false, false, 0, 0 ) \
46 BUILTIN (getuid, false, false, false, 0, 0 ) \
47 BUILTIN (getpwnam, false, true, false, 1, 1 ) \
48 BUILTIN (getpwuid, false, true, false, 1, 1 ) \
49 BUILTIN (hostname, false, false, false, 0, 0 ) \
50 BUILTIN (rand, false, false, false, 0, 0 ) \
51 BUILTIN (srand, false, false, false, 0, 1 ) \
52 BUILTIN (setenv, false, true, false, 2, 3 ) \
53 BUILTIN (unsetenv, false, true, false, 1, 1 ) \
54 BUILTIN (uname, false, false, false, 0, 0 ) \
57 #define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler);
61 static const m4_builtin m4_builtin_table
[] =
63 #define BUILTIN(handler, macros, blind, side, min, max) \
64 M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
69 { NULL
, NULL
, 0, 0, 0 },
74 include_stdlib (m4
*context
, m4_module
*module
, m4_obstack
*obs
)
76 m4_install_builtins (context
, module
, m4_builtin_table
);
83 M4BUILTIN_HANDLER (getcwd
)
85 /* FIXME - Use gnulib module for arbitrary-length cwd. */
89 bp
= getcwd (buf
, sizeof buf
);
91 if (bp
!= NULL
) /* in case of error return null string */
92 m4_shipout_string (context
, obs
, buf
, SIZE_MAX
, false);
98 M4BUILTIN_HANDLER (getenv
)
102 env
= getenv (M4ARG (1));
105 m4_shipout_string (context
, obs
, env
, SIZE_MAX
, false);
109 * setenv(NAME, VALUE, [OVERWRITE])
111 M4BUILTIN_HANDLER (setenv
)
116 if (!m4_numeric_arg (context
, m4_arg_info (argv
), M4ARG (3), M4ARGLEN (3),
120 /* TODO - error checking. */
121 setenv (M4ARG (1), M4ARG (2), overwrite
);
127 M4BUILTIN_HANDLER (unsetenv
)
129 /* TODO - error checking. */
130 unsetenv (M4ARG (1));
136 M4BUILTIN_HANDLER (getlogin
)
143 m4_shipout_string (context
, obs
, login
, SIZE_MAX
, false);
149 M4BUILTIN_HANDLER (getpid
)
151 m4_shipout_int (obs
, getpid ());
157 M4BUILTIN_HANDLER (getppid
)
159 m4_shipout_int (obs
, getppid ());
165 M4BUILTIN_HANDLER (getpwnam
)
169 pw
= getpwnam (M4ARG (1));
173 m4_shipout_string (context
, obs
, pw
->pw_name
, SIZE_MAX
, true);
174 obstack_1grow (obs
, ',');
175 m4_shipout_string (context
, obs
, pw
->pw_passwd
, SIZE_MAX
, true);
176 obstack_1grow (obs
, ',');
177 m4_shipout_int (obs
, pw
->pw_uid
);
178 obstack_1grow (obs
, ',');
179 m4_shipout_int (obs
, pw
->pw_gid
);
180 obstack_1grow (obs
, ',');
181 m4_shipout_string (context
, obs
, pw
->pw_gecos
, SIZE_MAX
, true);
182 obstack_1grow (obs
, ',');
183 m4_shipout_string (context
, obs
, pw
->pw_dir
, SIZE_MAX
, true);
184 obstack_1grow (obs
, ',');
185 m4_shipout_string (context
, obs
, pw
->pw_shell
, SIZE_MAX
, true);
192 M4BUILTIN_HANDLER (getpwuid
)
197 if (!m4_numeric_arg (context
, m4_arg_info (argv
), M4ARG (1), M4ARGLEN (1),
205 m4_shipout_string (context
, obs
, pw
->pw_name
, SIZE_MAX
, true);
206 obstack_1grow (obs
, ',');
207 m4_shipout_string (context
, obs
, pw
->pw_passwd
, SIZE_MAX
, true);
208 obstack_1grow (obs
, ',');
209 m4_shipout_int (obs
, pw
->pw_uid
);
210 obstack_1grow (obs
, ',');
211 m4_shipout_int (obs
, pw
->pw_gid
);
212 obstack_1grow (obs
, ',');
213 m4_shipout_string (context
, obs
, pw
->pw_gecos
, SIZE_MAX
, true);
214 obstack_1grow (obs
, ',');
215 m4_shipout_string (context
, obs
, pw
->pw_dir
, SIZE_MAX
, true);
216 obstack_1grow (obs
, ',');
217 m4_shipout_string (context
, obs
, pw
->pw_shell
, SIZE_MAX
, true);
224 M4BUILTIN_HANDLER (hostname
)
228 if (gethostname (buf
, sizeof buf
) < 0)
231 m4_shipout_string (context
, obs
, buf
, SIZE_MAX
, false);
237 M4BUILTIN_HANDLER (rand
)
239 m4_shipout_int (obs
, rand ());
245 M4BUILTIN_HANDLER (srand
)
250 seed
= time (0L) * getpid ();
253 if (!m4_numeric_arg (context
, m4_arg_info (argv
), M4ARG (1),
254 M4ARGLEN (1), &seed
))
264 M4BUILTIN_HANDLER (uname
)
268 if (uname (&ut
) == 0)
270 m4_shipout_string (context
, obs
, ut
.sysname
, SIZE_MAX
, true);
271 obstack_1grow (obs
, ',');
272 m4_shipout_string (context
, obs
, ut
.nodename
, SIZE_MAX
, true);
273 obstack_1grow (obs
, ',');
274 m4_shipout_string (context
, obs
, ut
.release
, SIZE_MAX
, true);
275 obstack_1grow (obs
, ',');
276 m4_shipout_string (context
, obs
, ut
.version
, SIZE_MAX
, true);
277 obstack_1grow (obs
, ',');
278 m4_shipout_string (context
, obs
, ut
.machine
, SIZE_MAX
, true);
285 M4BUILTIN_HANDLER (getuid
)
287 m4_shipout_int (obs
, getuid ());