VirtualBox

source: kBuild/trunk/src/kmk/kmkbuiltin/append.c@ 2113

最後變更 在這個檔案從2113是 2113,由 bird 提交於 16 年 前

kmkbuiltin: include config.h

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 7.1 KB
 
1/* $Id: append.c 2113 2008-12-25 13:21:58Z bird $ */
2/** @file
3 * kMk Builtin command - append text to file.
4 */
5
6/*
7 * Copyright (c) 2005-2008 knut st. osmundsen <[email protected]>
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 3 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, see <http://www.gnu.org/licenses/>
23 *
24 */
25
26/*******************************************************************************
27* Header Files *
28*******************************************************************************/
29#ifndef kmk_builtin_append
30# include "make.h"
31# include "filedef.h"
32# include "variable.h"
33#else
34# include "config.h"
35#endif
36#include <string.h>
37#include <stdio.h>
38#include "err.h"
39#include "kmkbuiltin.h"
40
41
42/**
43 * Prints the usage and return 1.
44 */
45static int usage(FILE *pf)
46{
47 fprintf(pf,
48 "usage: %s [-dcnNtv] file [string ...]\n"
49 " or: %s --version\n"
50 " or: %s --help\n"
51 "\n"
52 "Options:\n"
53 " -d Enclose the output in define ... endef, taking the name from\n"
54 " the first argument following the file name.\n"
55 " -c Output the command for specified target(s). [builtin only]\n"
56 " -n Insert a newline between the strings.\n"
57 " -N Suppress the trailing newline.\n"
58 " -t Truncate the file instead of appending\n"
59 " -v Output the value(s) for specified variable(s). [builtin only]\n"
60 ,
61 g_progname, g_progname, g_progname);
62 return 1;
63}
64
65
66/**
67 * Appends text to a textfile, creating the textfile if necessary.
68 */
69int kmk_builtin_append(int argc, char **argv, char **envp)
70{
71 int i;
72 int fFirst;
73 int iFile;
74 FILE *pFile;
75 int fNewline = 0;
76 int fNoTrailingNewline = 0;
77 int fTruncate = 0;
78 int fDefine = 0;
79 int fVariables = 0;
80 int fCommands = 0;
81
82 g_progname = argv[0];
83
84 /*
85 * Parse options.
86 */
87 i = 1;
88 while (i < argc
89 && argv[i][0] == '-'
90 && argv[i][1] != '\0' /* '-' is a file */
91 && strchr("-cdnNtv", argv[i][1]) /* valid option char */
92 )
93 {
94 char *psz = &argv[i][1];
95 if (*psz != '-')
96 {
97 do
98 {
99 switch (*psz)
100 {
101 case 'c':
102 if (fVariables)
103 {
104 errx(1, "Option '-c' clashes with '-v'.");
105 return usage(stderr);
106 }
107#ifndef kmk_builtin_append
108 fCommands = 1;
109 break;
110#else
111 errx(1, "Option '-c' isn't supported in external mode.");
112 return usage(stderr);
113#endif
114 case 'd':
115 if (fVariables)
116 {
117 errx(1, "Option '-d' must come before '-v'!");
118 return usage(stderr);
119 }
120 fDefine = 1;
121 break;
122 case 'n':
123 fNewline = 1;
124 break;
125 case 'N':
126 fNoTrailingNewline = 1;
127 break;
128 case 't':
129 fTruncate = 1;
130 break;
131 case 'v':
132 if (fCommands)
133 {
134 errx(1, "Option '-v' clashes with '-c'.");
135 return usage(stderr);
136 }
137#ifndef kmk_builtin_append
138 fVariables = 1;
139 break;
140#else
141 errx(1, "Option '-v' isn't supported in external mode.");
142 return usage(stderr);
143#endif
144 default:
145 errx(1, "Invalid option '%c'! (%s)", *psz, argv[i]);
146 return usage(stderr);
147 }
148 } while (*++psz);
149 }
150 else if (!strcmp(psz, "-help"))
151 {
152 usage(stdout);
153 return 0;
154 }
155 else if (!strcmp(psz, "-version"))
156 return kbuild_version(argv[0]);
157 else
158 break;
159 i++;
160 }
161
162 if (i + fDefine >= argc)
163 {
164 if (i <= argc)
165 errx(1, "missing filename!");
166 else
167 errx(1, "missing define name!");
168 return usage(stderr);
169 }
170
171 /*
172 * Open the output file.
173 */
174 iFile = i;
175 pFile = fopen(argv[i], fTruncate ? "w" : "a");
176 if (!pFile)
177 return err(1, "failed to open '%s'.", argv[i]);
178
179 /*
180 * Start define?
181 */
182 if (fDefine)
183 {
184 i++;
185 fprintf(pFile, "define %s\n", argv[i]);
186 }
187
188 /*
189 * Append the argument strings to the file
190 */
191 fFirst = 1;
192 for (i++; i < argc; i++)
193 {
194 const char *psz = argv[i];
195 size_t cch = strlen(psz);
196 if (!fFirst)
197 fputc(fNewline ? '\n' : ' ', pFile);
198#ifndef kmk_builtin_append
199 if (fCommands)
200 {
201 char *pszOldBuf;
202 unsigned cchOldBuf;
203 char *pchEnd;
204
205 install_variable_buffer(&pszOldBuf, &cchOldBuf);
206
207 pchEnd = func_commands(variable_buffer, &argv[i], "commands");
208 fwrite(variable_buffer, 1, pchEnd - variable_buffer, pFile);
209
210 restore_variable_buffer(pszOldBuf, cchOldBuf);
211 }
212 else if (fVariables)
213 {
214 struct variable *pVar = lookup_variable(psz, cch);
215 if (!pVar)
216 continue;
217 if ( pVar->recursive
218 && memchr(pVar->value, '$', pVar->value_length))
219 {
220 char *pszExpanded = allocated_variable_expand(pVar->value);
221 fwrite(pszExpanded, 1, strlen(pszExpanded), pFile);
222 free(pszExpanded);
223 }
224 else
225 fwrite(pVar->value, 1, pVar->value_length, pFile);
226 }
227 else
228#endif
229 fwrite(psz, 1, cch, pFile);
230 fFirst = 0;
231 }
232
233 /*
234 * End the define?
235 */
236 if (fDefine)
237 {
238 if (fFirst)
239 fwrite("\nendef", 1, sizeof("\nendef") - 1, pFile);
240 else
241 fwrite("endef", 1, sizeof("endef") - 1, pFile);
242 }
243
244 /*
245 * Add the final newline (unless supressed) and close the file.
246 */
247 if ( ( !fNoTrailingNewline
248 && fputc('\n', pFile) == EOF)
249 || ferror(pFile))
250 {
251 fclose(pFile);
252 return errx(1, "error writing to '%s'!", argv[iFile]);
253 }
254 if (fclose(pFile))
255 return err(1, "failed to fclose '%s'!", argv[iFile]);
256 return 0;
257}
258
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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