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

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

Added kmk_builtin_append.

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