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

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

All commands are everywhere now.

  • 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 376 2005-12-18 06:39:23Z 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 rc;
165
166 /*
167 * Check and skip the prefix.
168 */
169 if (strncmp(pszCmd, "kmk_builtin_", sizeof("kmk_builtin_") - 1))
170 {
171 printf("kmk_builtin: Invalid command prefix '%s'!\n", pszCmd);
172 return 1;
173 }
174 pszCmd += sizeof("kmk_builtin_") - 1;
175
176 /*
177 * String switch on the command.
178 */
179 if (!strcmp(pszCmd, "append"))
180 rc = kmk_builtin_append(argc, argv, environ);
181 else if (!strcmp(pszCmd, "echo"))
182 rc = kmk_builtin_echo(argc, argv, environ);
183 else if (!strcmp(pszCmd, "install"))
184 rc = kmk_builtin_install(argc, argv, environ);
185 else if (!strcmp(pszCmd, "ln"))
186 rc = kmk_builtin_ln(argc, argv, environ);
187 else if (!strcmp(pszCmd, "mkdir"))
188 rc = kmk_builtin_mkdir(argc, argv, environ);
189 //else if (!strcmp(pszCmd, "mv"))
190 // rc = kmk_builtin_mv(argc, argv, environ);
191 else if (!strcmp(pszCmd, "rm"))
192 rc = kmk_builtin_rm(argc, argv, environ);
193 //else if (!strcmp(pszCmd, "rmdir"))
194 // rc = kmk_builtin_rmdir(argc, argv, environ);
195 /* obsolete */
196 else if (!strcmp(pszCmd, "cp"))
197 rc = kmk_builtin_cp(argc, argv, environ);
198 else
199 {
200 printf("kmk_builtin: Unknown command '%s'!\n", pszCmd);
201 return 1;
202 }
203 g_progname = "kmk"; /* paranoia, make sure it's not pointing at a freed argv[0]. */
204 return rc;
205}
206
Note: See TracBrowser for help on using the repository browser.