source: trunk/src/gmake/kmkbuiltin.c@ 377

Last change on this file since 377 was 377, checked in by bird, 20 years ago

Save and restore umask.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.4 KB
Line 
1/* $Id: kmkbuiltin.c 377 2005-12-18 12:28:07Z bird $ */
2/** @file
3 *
4 * kMk Builtin command execution.
5 *
6 * Copyright (c) 2005 knut st. osmundsen <bird@innotek.de>
7 *
8 *
9 * This file is part of kBuild.
10 *
11 * kBuild is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * kBuild is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kBuild; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#include <string.h>
28#include <stdlib.h>
29#include <stdio.h>
30#include <ctype.h>
31#include "kmkbuiltin/err.h"
32#include "kmkbuiltin.h"
33
34extern char **environ;
35
36int kmk_builtin_command(const char *pszCmd)
37{
38 int argc;
39 char **argv;
40 char *psz;
41 int rc;
42
43 /*
44 * Check and skip the prefix.
45 */
46 if (strncmp(pszCmd, "kmk_builtin_", sizeof("kmk_builtin_") - 1))
47 {
48 printf("kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);
49 return 1;
50 }
51
52 /*
53 * Parse arguments.
54 */
55 argc = 0;
56 argv = NULL;
57 while (*pszCmd)
58 {
59 const char *pszEnd;
60 const char *pszNext;
61 int fEscaped = 0;
62 size_t cch;
63
64 /*
65 * Find start and end of the current command.
66 */
67 if (*pszCmd == '"' || *pszCmd == '\'')
68 {
69 pszEnd = pszCmd;
70 for (;;)
71 {
72 pszEnd = strchr(pszEnd + 1, *pszCmd);
73 if (!pszEnd)
74 {
75 printf("kmk_builtin: Unbalanced quote in argument %d: %s\n", argc + 1, pszCmd);
76 while (argc--)
77 free(argv[argc]);
78 free(argv);
79 return 1;
80 }
81 /* two quotes -> escaped quote. */
82 if (pszEnd[0] != pszEnd[1])
83 break;
84 fEscaped = 1;
85 }
86 pszNext = pszEnd + 1;
87 pszCmd++;
88 }
89 else
90 {
91 pszEnd = pszCmd;
92 while (!isspace(*pszEnd) && *pszEnd)
93 pszEnd++;
94 pszNext = pszEnd;
95 }
96
97 /*
98 * Make argument.
99 */
100 if (!(argc % 16))
101 {
102 void *pv = realloc(argv, sizeof(char *) * (argc + 17));
103 if (!pv)
104 {
105 printf("kmk_builtin: out of memory. argc=%d\n", argc);
106 break;
107 }
108 argv = (char **)pv;
109 }
110 cch = pszEnd - pszCmd;
111 argv[argc] = malloc(cch + 1);
112 if (!argv[argc])
113 {
114 printf("kmk_builtin: out of memory. argc=%d len=%d\n", argc, pszEnd - pszCmd + 1);
115 break;
116 }
117 memcpy(argv[argc], pszCmd, cch);
118 argv[argc][cch] = '\0';
119
120 /* unescape quotes? */
121 if (fEscaped)
122 {
123 char ch = pszCmd[-1];
124 char *pszW = argv[argc];
125 char *pszR = argv[argc];
126 while (*pszR)
127 {
128 if (*pszR == ch)
129 pszR++;
130 *pszW++ = *pszR++;
131 }
132 *pszW = '\0';
133 }
134 /* commit it */
135 argv[++argc] = NULL;
136
137 /*
138 * Next
139 */
140 pszCmd = pszNext;
141 if (isspace(*pszCmd) && *pszCmd)
142 pszCmd++;
143 }
144
145 /*
146 * Execute the command if parsing was successful.
147 */
148 if (!*pszCmd)
149 rc = kmk_builtin_command_parsed(argc, argv);
150 else
151 rc = 1;
152
153 /* clean up and return. */
154 while (argc--)
155 free(argv[argc]);
156 free(argv);
157 return rc;
158}
159
160
161int kmk_builtin_command_parsed(int argc, char **argv)
162{
163 const char *pszCmd = argv[0];
164 int iumask;
165 int rc;
166
167 /*
168 * Check and skip the prefix.
169 */
170 if (strncmp(pszCmd, "kmk_builtin_", sizeof("kmk_builtin_") - 1))
171 {
172 printf("kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);
173 return 1;
174 }
175 pszCmd += sizeof("kmk_builtin_") - 1;
176
177 /*
178 * String switch on the command.
179 */
180 iumask = umask(0);
181 umask(iumask);
182 if (!strcmp(pszCmd, "append"))
183 rc = kmk_builtin_append(argc, argv, environ);
184 else if (!strcmp(pszCmd, "echo"))
185 rc = kmk_builtin_echo(argc, argv, environ);
186 else if (!strcmp(pszCmd, "install"))
187 rc = kmk_builtin_install(argc, argv, environ);
188 else if (!strcmp(pszCmd, "ln"))
189 rc = kmk_builtin_ln(argc, argv, environ);
190 else if (!strcmp(pszCmd, "mkdir"))
191 rc = kmk_builtin_mkdir(argc, argv, environ);
192 //else if (!strcmp(pszCmd, "mv"))
193 // rc = kmk_builtin_mv(argc, argv, environ);
194 else if (!strcmp(pszCmd, "rm"))
195 rc = kmk_builtin_rm(argc, argv, environ);
196 //else if (!strcmp(pszCmd, "rmdir"))
197 // rc = kmk_builtin_rmdir(argc, argv, environ);
198 /* obsolete */
199 else if (!strcmp(pszCmd, "cp"))
200 rc = kmk_builtin_cp(argc, argv, environ);
201 else
202 {
203 printf("kmk_builtin: Unknown command '%s'!\n", pszCmd);
204 return 1;
205 }
206 g_progname = "kmk"; /* paranoia, make sure it's not pointing at a freed argv[0]. */
207 umask(iumask);
208 return rc;
209}
210
Note: See TracBrowser for help on using the repository browser.