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

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

ln and install builtins (from BSD as usual).

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