VirtualBox

source: kBuild/trunk/src/gmakenew/kmkbuiltin.c@ 944

Last change on this file since 944 was 803, checked in by bird, 18 years ago

msvcrt build.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.7 KB
Line 
1/* $Id: kmkbuiltin.c 803 2007-01-25 00:49:28Z bird $ */
2/** @file
3 *
4 * kMk Builtin command execution.
5 *
6 * Copyright (c) 2005-2007 knut st. osmundsen <[email protected]>
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#ifdef _MSC_VER
32# include <io.h>
33#endif
34#include "kmkbuiltin/err.h"
35#include "kmkbuiltin.h"
36
37#ifndef _MSC_VER
38extern char **environ;
39#endif
40
41int kmk_builtin_command(const char *pszCmd)
42{
43 int argc;
44 char **argv;
45 int rc;
46
47 /*
48 * Check and skip the prefix.
49 */
50 if (strncmp(pszCmd, "kmk_builtin_", sizeof("kmk_builtin_") - 1))
51 {
52 printf("kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);
53 return 1;
54 }
55
56 /*
57 * Parse arguments.
58 */
59 argc = 0;
60 argv = NULL;
61 while (*pszCmd)
62 {
63 const char *pszEnd;
64 const char *pszNext;
65 int fEscaped = 0;
66 size_t cch;
67
68 /*
69 * Find start and end of the current command.
70 */
71 if (*pszCmd == '"' || *pszCmd == '\'')
72 {
73 pszEnd = pszCmd;
74 for (;;)
75 {
76 pszEnd = strchr(pszEnd + 1, *pszCmd);
77 if (!pszEnd)
78 {
79 printf("kmk_builtin: Unbalanced quote in argument %d: %s\n", argc + 1, pszCmd);
80 while (argc--)
81 free(argv[argc]);
82 free(argv);
83 return 1;
84 }
85 /* two quotes -> escaped quote. */
86 if (pszEnd[0] != pszEnd[1])
87 break;
88 fEscaped = 1;
89 }
90 pszNext = pszEnd + 1;
91 pszCmd++;
92 }
93 else
94 {
95 pszEnd = pszCmd;
96 while (!isspace(*pszEnd) && *pszEnd)
97 pszEnd++;
98 pszNext = pszEnd;
99 }
100
101 /*
102 * Make argument.
103 */
104 if (!(argc % 16))
105 {
106 void *pv = realloc(argv, sizeof(char *) * (argc + 17));
107 if (!pv)
108 {
109 printf("kmk_builtin: out of memory. argc=%d\n", argc);
110 break;
111 }
112 argv = (char **)pv;
113 }
114 cch = pszEnd - pszCmd;
115 argv[argc] = malloc(cch + 1);
116 if (!argv[argc])
117 {
118 printf("kmk_builtin: out of memory. argc=%d len=%d\n", argc, pszEnd - pszCmd + 1);
119 break;
120 }
121 memcpy(argv[argc], pszCmd, cch);
122 argv[argc][cch] = '\0';
123
124 /* unescape quotes? */
125 if (fEscaped)
126 {
127 char ch = pszCmd[-1];
128 char *pszW = argv[argc];
129 char *pszR = argv[argc];
130 while (*pszR)
131 {
132 if (*pszR == ch)
133 pszR++;
134 *pszW++ = *pszR++;
135 }
136 *pszW = '\0';
137 }
138 /* commit it */
139 argv[++argc] = NULL;
140
141 /*
142 * Next
143 */
144 pszCmd = pszNext;
145 if (isspace(*pszCmd) && *pszCmd)
146 pszCmd++;
147 }
148
149 /*
150 * Execute the command if parsing was successful.
151 */
152 if (!*pszCmd)
153 rc = kmk_builtin_command_parsed(argc, argv);
154 else
155 rc = 1;
156
157 /* clean up and return. */
158 while (argc--)
159 free(argv[argc]);
160 free(argv);
161 return rc;
162}
163
164
165int kmk_builtin_command_parsed(int argc, char **argv)
166{
167 const char *pszCmd = argv[0];
168 int iumask;
169 int rc;
170
171 /*
172 * Check and skip the prefix.
173 */
174 if (strncmp(pszCmd, "kmk_builtin_", sizeof("kmk_builtin_") - 1))
175 {
176 printf("kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);
177 return 1;
178 }
179 pszCmd += sizeof("kmk_builtin_") - 1;
180
181 /*
182 * String switch on the command.
183 */
184 iumask = umask(0);
185 umask(iumask);
186 if (!strcmp(pszCmd, "append"))
187 rc = kmk_builtin_append(argc, argv, environ);
188 else if (!strcmp(pszCmd, "printf"))
189 rc = kmk_builtin_printf(argc, argv, environ);
190 else if (!strcmp(pszCmd, "echo"))
191 rc = kmk_builtin_echo(argc, argv, environ);
192 else if (!strcmp(pszCmd, "install"))
193 rc = kmk_builtin_install(argc, argv, environ);
194 else if (!strcmp(pszCmd, "ln"))
195 rc = kmk_builtin_ln(argc, argv, environ);
196 else if (!strcmp(pszCmd, "mkdir"))
197 rc = kmk_builtin_mkdir(argc, argv, environ);
198 else if (!strcmp(pszCmd, "mv"))
199 rc = kmk_builtin_mv(argc, argv, environ);
200 else if (!strcmp(pszCmd, "rm"))
201 rc = kmk_builtin_rm(argc, argv, environ);
202 else if (!strcmp(pszCmd, "rmdir"))
203 rc = kmk_builtin_rmdir(argc, argv, environ);
204 /* rarely used commands: */
205 else if (!strcmp(pszCmd, "cat"))
206 rc = kmk_builtin_cat(argc, argv, environ);
207 else if (!strcmp(pszCmd, "cp"))
208 rc = kmk_builtin_cp(argc, argv, environ);
209 else
210 {
211 printf("kmk_builtin: Unknown command '%s'!\n", pszCmd);
212 return 1;
213 }
214 g_progname = "kmk"; /* paranoia, make sure it's not pointing at a freed argv[0]. */
215 umask(iumask);
216 return rc;
217}
218
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette