VirtualBox

source: vbox/trunk/src/bldprogs/VBoxCPP.cpp@ 41177

Last change on this file since 41177 was 41177, checked in by vboxsync, 13 years ago

VBoxCPP: just started hacking -> laptop.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 KB
Line 
1/* $Id: VBoxCPP.cpp 41177 2012-05-05 21:00:34Z vboxsync $ */
2/** @file
3 * VBox Build Tool - A mini C Preprocessor.
4 */
5
6/*
7 * Copyright (C) 2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <VBox/VBoxTpG.h>
23
24#include <iprt/alloca.h>
25#include <iprt/assert.h>
26#include <iprt/ctype.h>
27#include <iprt/env.h>
28#include <iprt/err.h>
29#include <iprt/file.h>
30#include <iprt/getopt.h>
31#include <iprt/initterm.h>
32#include <iprt/list.h>
33#include <iprt/mem.h>
34#include <iprt/message.h>
35#include <iprt/path.h>
36#include <iprt/process.h>
37#include <iprt/stream.h>
38#include <iprt/string.h>
39#include <iprt/uuid.h>
40
41#include "scmstream.h"
42
43
44
45/*******************************************************************************
46* Structures and Typedefs *
47*******************************************************************************/
48/**
49 * The preprocessor mode.
50 */
51typedef enum VBCPPMODE
52{
53 kVBCppMode_Invalid = 0,
54/* kVBCppMode_Full,*/
55 kVBCppMode_Selective,
56 kVBCppMode_SelectiveD,
57 kVBCppMode_End
58} VBCPPMODE;
59
60
61/**
62 * A define.
63 */
64typedef struct VBCPPDEF
65{
66 /** The string space core. */
67 RTSTRSPACECORE Core;
68 /** Whether it's a function. */
69 bool fFunction;
70 /** Variable argument count. */
71 bool fVarArg;
72 /** The number of known arguments.*/
73 uint32_t cArgs;
74
75 /** @todo More to come later some day... Currently, only care about selective
76 * preprocessing. */
77
78 /** The define value. (This is followed by the name). */
79 char szValue[1];
80} VBCPPDEF;
81/** Pointer to a define. */
82typedef VBCPPDEF *PVBCPPDEF;
83
84
85/**
86 * C Preprocessor instance data.
87 */
88typedef struct VBCPP
89{
90 /** @name Options
91 * @{ */
92 /** The preprocessing mode. */
93 VBCPPMODE enmMode;
94 /** Whether to keep comments. */
95 bool fKeepComments;
96
97 /** The number of include directories. */
98 uint32_t cIncludes;
99 /** Array of directories to search for include files. */
100 const char **papszIncludes;
101
102 /** The name of the input file. */
103 const char *pszInput;
104 /** The name of the output file. NULL if stdout. */
105 const char *pszOutput;
106 /** @} */
107
108 /** The define string space. */
109 RTSTRSPACE StrSpace;
110 /** Indicates whether a C-word might need expansion.
111 * The bitmap is indexed by C-word lead character. Bits that are set
112 * indicates that the lead character is used in a \#define that we know and
113 * should expand. */
114 uint32_t bmDefined[256/32];
115} VBCPP;
116/** Pointer to the C preprocessor instance data. */
117typedef VBCPP *PVBCPP;
118
119
120/*******************************************************************************
121* Global Variables *
122*******************************************************************************/
123
124
125
126static void vbcppInit(PVBCPP pThis)
127{
128 pThis->enmMode = kVBCppMode_Selective;
129 pThis->fKeepComments = true;
130 pThis->cIncludes = 0;
131 pThis->cIncludes = 0;
132 pThis->papszIncludes = NULL;
133 pThis->pszInput = NULL;
134 pThis->pszOutput = NULL;
135 pThis->StrSpace = NULL;
136 RT_ZERO(pThis->bmDefined);
137
138}
139
140
141/**
142 * Removes a define.
143 *
144 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg.
145 * @param pThis The C processor instance.
146 * @param pszDefine The define name, no argument list or anything.
147 * @param cchDefine The length of the name. RTSTR_MAX is ok.
148 */
149static RTEXITCODE vbcppRemoveDefine(PVBCPP pThis, const char *pszDefine, size_t cchDefine)
150{
151 PRTSTRSPACECORE pHit = RTStrSpaceGetN(&pThis->StrSpace, pszDefine, cchDefine);
152 if (pHit)
153 {
154 RTStrSpaceRemove(&pThis->StrSpace, pHit->pszString);
155 RTMemFree(pHit);
156 }
157 return RTEXITCODE_SUCCESS;
158}
159
160
161/**
162 * Adds a define.
163 *
164 * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + msg.
165 * @param pThis The C processor instance.
166 * @param pszDefine The define name and optionally the argument
167 * list.
168 * @param cchDefine The length of the name. RTSTR_MAX is ok.
169 * @param pszValue The value.
170 * @param cchDefine The length of the value. RTSTR_MAX is ok.
171 */
172static RTEXITCODE vbcppAddDefine(PVBCPP pThis, const char *pszDefine, size_t cchDefine,
173 const char *pszValue, size_t cchValue)
174{
175 if (cchDefine == RTSTR_MAX)
176 cchDefine = strlen(pszDefine);
177 if (cchValue == RTSTR_MAX)
178 cchValue = strlen(pszValue);
179
180 const char *pszParan = (const char *)memchr(pszDefine, '(', cchDefine);
181 if (pszParan)
182 return RTMsgErrorExit(RTEXITCODE_FAILURE, "function defines are not implemented. sorry");
183
184 PVBCPPDEF pDef = (PVBCPPDEF)RTMemAlloc(sizeof(*pDef) + cchValue + cchDefine + 2);
185 if (!pDef)
186 return RTMsgErrorExit(RTEXITCODE_FAILURE, "out of memory");
187
188 pDef->fFunction = false;
189 pDef->fVarArg = false;
190 pDef->cArgs = 0;
191 memcpy(pDef->szValue, pszValue, cchValue);
192 pDef->szValue[cchValue] = '\0';
193 pDef->Core.pszString = &pDef->szValue[cchValue + 1];
194 memcpy(&pDef->szValue[cchValue + 1], pszDefine, cchDefine);
195 pDef->szValue[cchValue + 1 + cchDefine] = '\0';
196
197 if (!RTStrSpaceInsert(&pThis->StrSpace, &pDef->Core))
198 {
199 RTMsgWarning("Redefining '%s'\n", pDef->Core.pszString);
200 vbcppRemoveDefine(pThis, pDef->Core.pszString, cchDefine);
201 RTStrSpaceInsert(&pThis->StrSpace, &pDef->Core);
202 }
203 return RTEXITCODE_SUCCESS;
204}
205
206static RTEXITCODE vbcppAddInclude(PVBCPP pThis, const char *pszDir)
207{
208 return RTEXITCODE_SUCCESS;
209}
210
211
212/**
213 * Parses the command line options.
214 *
215 * @returns Program exit code. Exit on non-success or if *pfExit is set.
216 * @param pThis The C preprocessor instance.
217 * @param argc The argument count.
218 * @param argv The argument vector.
219 * @param pfExit Pointer to the exit indicator.
220 */
221static RTEXITCODE vbcppParseOptions(PVBCPP pThis, int argc, char **argv, bool *pfExit)
222{
223 RTEXITCODE rcExit;
224
225 *pfExit = false;
226
227 /*
228 * Option config.
229 */
230 static RTGETOPTDEF const s_aOpts[] =
231 {
232 { "--define", 'D', RTGETOPT_REQ_STRING },
233 { "--include-dir", 'I', RTGETOPT_REQ_STRING },
234 { "--undefine", 'U', RTGETOPT_REQ_STRING },
235 { "--D-strip", 'd', RTGETOPT_REQ_NOTHING },
236 };
237
238 RTGETOPTUNION ValueUnion;
239 RTGETOPTSTATE GetOptState;
240 int rc = RTGetOptInit(&GetOptState, argc, argv, &s_aOpts[0], RT_ELEMENTS(s_aOpts), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
241 AssertReleaseRCReturn(rc, RTEXITCODE_FAILURE);
242
243 /*
244 * Process the options.
245 */
246 while ((rc = RTGetOpt(&GetOptState, &ValueUnion)) != 0)
247 {
248 switch (rc)
249 {
250 case 'd':
251 pThis->enmMode = kVBCppMode_SelectiveD;
252 break;
253
254 case 'D':
255 {
256 const char *pszEqual = strchr(ValueUnion.psz, '=');
257 if (pszEqual)
258 rcExit = vbcppAddDefine(pThis, ValueUnion.psz, pszEqual - ValueUnion.psz, pszEqual + 1, RTSTR_MAX);
259 else
260 rcExit = vbcppAddDefine(pThis, ValueUnion.psz, RTSTR_MAX, "1", 1);
261 if (rcExit != RTEXITCODE_SUCCESS)
262 return rcExit;
263 break;
264 }
265
266 case 'I':
267 rcExit = vbcppAddInclude(pThis, ValueUnion.psz);
268 if (rcExit != RTEXITCODE_SUCCESS)
269 return rcExit;
270 break;
271
272 case 'U':
273 rcExit = vbcppRemoveDefine(pThis, ValueUnion.psz, RTSTR_MAX);
274 break;
275
276 case 'h':
277 RTPrintf("No help yet, sorry\n");
278 *pfExit = true;
279 return RTEXITCODE_SUCCESS;
280
281 case 'V':
282 {
283 /* The following is assuming that svn does it's job here. */
284 static const char s_szRev[] = "$Revision: 41177 $";
285 const char *psz = RTStrStripL(strchr(s_szRev, ' '));
286 RTPrintf("r%.*s\n", strchr(psz, ' ') - psz, psz);
287 *pfExit = true;
288 return RTEXITCODE_SUCCESS;
289 }
290
291 case VINF_GETOPT_NOT_OPTION:
292 if (!pThis->pszInput)
293 pThis->pszInput = ValueUnion.psz;
294 else if (!pThis->pszOutput)
295 pThis->pszOutput = ValueUnion.psz;
296 else
297 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "too many file arguments");
298 break;
299
300
301 /*
302 * Errors and bugs.
303 */
304 default:
305 return RTGetOptPrintError(rc, &ValueUnion);
306 }
307 }
308
309 return RTEXITCODE_SUCCESS;
310}
311
312
313
314
315int main(int argc, char **argv)
316{
317 int rc = RTR3InitExe(argc, &argv, 0);
318 if (RT_FAILURE(rc))
319 return RTMsgInitFailure(rc);
320
321 /*
322 * Parse options.
323 */
324 VBCPP This;
325 vbcppInit(&This);
326 bool fExit;
327 RTEXITCODE rcExit = vbcppParseOptions(&This, argc, argv, &fExit);
328 if (!fExit && rcExit == RTEXITCODE_SUCCESS)
329 {
330 /*
331 * Process the input file.
332 */
333
334 }
335
336 return rcExit;
337}
338
339
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