summaryrefslogtreecommitdiffstats
path: root/src/bldprogs/scm.h
blob: 7f778405fbe2642b4ceb67e426d4c90db497420b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
/* $Id: scm.h $ */
/** @file
 * IPRT Testcase / Tool - Source Code Massager.
 */

/*
 * Copyright (C) 2010-2022 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * SPDX-License-Identifier: GPL-3.0-only
 */

#ifndef VBOX_INCLUDED_SRC_bldprogs_scm_h
#define VBOX_INCLUDED_SRC_bldprogs_scm_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif

#include "scmstream.h"

RT_C_DECLS_BEGIN

/** Pointer to the rewriter state. */
typedef struct SCMRWSTATE *PSCMRWSTATE;
/** Pointer to const massager settings. */
typedef struct SCMSETTINGSBASE const *PCSCMSETTINGSBASE;


/** @name Subversion Access
 * @{  */

/**
 * SVN property.
 */
typedef struct SCMSVNPROP
{
    /** The property. */
    char           *pszName;
    /** The value.
     * When used to record updates, this can be set to NULL to trigger the
     * deletion of the property. */
    char           *pszValue;
} SCMSVNPROP;
/** Pointer to a SVN property. */
typedef SCMSVNPROP *PSCMSVNPROP;
/** Pointer to a const  SVN property. */
typedef SCMSVNPROP const *PCSCMSVNPROP;


void ScmSvnInit(void);
void ScmSvnTerm(void);
bool ScmSvnIsDirInWorkingCopy(const char *pszDir);
bool ScmSvnIsInWorkingCopy(PSCMRWSTATE pState);
int  ScmSvnQueryProperty(PSCMRWSTATE pState, const char *pszName, char **ppszValue);
int  ScmSvnQueryParentProperty(PSCMRWSTATE pState, const char *pszName, char **ppszValue);
int  ScmSvnSetProperty(PSCMRWSTATE pState, const char *pszName, const char *pszValue);
int  ScmSvnDelProperty(PSCMRWSTATE pState, const char *pszName);
int  ScmSvnDisplayChanges(PSCMRWSTATE pState);
int  ScmSvnApplyChanges(PSCMRWSTATE pState);

/** @} */


/** @name Code Parsing
 * @{  */

/**
 * Comment style.
 */
typedef enum SCMCOMMENTSTYLE
{
    kScmCommentStyle_Invalid = 0,
    kScmCommentStyle_C,
    kScmCommentStyle_Hash,
    kScmCommentStyle_Python,    /**< Same as hash, except for copyright/license. */
    kScmCommentStyle_Semicolon,
    kScmCommentStyle_Rem_Upper,
    kScmCommentStyle_Rem_Lower,
    kScmCommentStyle_Rem_Camel,
    kScmCommentStyle_Sql,
    kScmCommentStyle_Tick,
    kScmCommentStyle_Xml,
    kScmCommentStyle_End
} SCMCOMMENTSTYLE;

/**
 * Comment types.
 */
typedef enum SCMCOMMENTTYPE
{
    kScmCommentType_Invalid = 0,                /**< Customary invalid zero value. */
    kScmCommentType_Line,                       /**< Line comment. */
    kScmCommentType_Line_JavaDoc,               /**< Line comment, JavaDoc style. */
    kScmCommentType_Line_JavaDoc_After,         /**< Line comment, JavaDoc after-member style. */
    kScmCommentType_Line_Qt,                    /**< Line comment, JavaDoc style. */
    kScmCommentType_Line_Qt_After,              /**< Line comment, JavaDoc after-member style. */
    kScmCommentType_MultiLine,                  /**< Multi-line comment (e.g. ansi C).  */
    kScmCommentType_MultiLine_JavaDoc,          /**< Multi-line comment, JavaDoc style.  */
    kScmCommentType_MultiLine_JavaDoc_After,    /**< Multi-line comment, JavaDoc after-member style.  */
    kScmCommentType_MultiLine_Qt,               /**< Multi-line comment, Qt style.  */
    kScmCommentType_MultiLine_Qt_After,         /**< Multi-line comment, Qt after-member style.  */
    kScmCommentType_DocString,                  /**< Triple quoted python doc string. */
    kScmCommentType_Xml,                        /**< XML comment style. */
    kScmCommentType_End                         /**< Customary exclusive end value. */
} SCMCOMMENTTYPE;


/**
 * Comment information.
 */
typedef struct SCMCOMMENTINFO
{
    /** Comment type. */
    SCMCOMMENTTYPE  enmType;
    /** Start line number  (0-based). */
    uint32_t        iLineStart;
    /** Start line offset (0-based). */
    uint32_t        offStart;
    /** End line number  (0-based). */
    uint32_t        iLineEnd;
    /** End line offset  (0-based). */
    uint32_t        offEnd;
    /** Number of blank lines before the body (@a pszBody). */
    uint32_t        cBlankLinesBefore;
    /** Number of blank lines after the body (@a pszBody + @a cchBody). */
    uint32_t        cBlankLinesAfter;
    /** @todo add min/max indent. Raw length. Etc. */
} SCMCOMMENTINFO;
/** Pointer to comment info. */
typedef SCMCOMMENTINFO *PSCMCOMMENTINFO;
/** Pointer to const comment info. */
typedef SCMCOMMENTINFO const *PCSCMCOMMENTINFO;


/**
 * Comment enumeration callback function.
 *
 * @returns IPRT style status code.  Failures causes immediate return.  While an
 *          informational status code is saved (first one) and returned later.
 * @param   pInfo           Additional comment info.
 * @param   pszBody         The comment body.  This is somewhat stripped.
 * @param   cchBody         The comment body length.
 * @param   pvUser          User callback argument.
 */
typedef DECLCALLBACKTYPE(int, FNSCMCOMMENTENUMERATOR,(PCSCMCOMMENTINFO pInfo, const char *pszBody, size_t cchBody, void *pvUser));
/** Poiter to a omment enumeration callback function. */
typedef FNSCMCOMMENTENUMERATOR *PFNSCMCOMMENTENUMERATOR;

int ScmEnumerateComments(PSCMSTREAM pIn, SCMCOMMENTSTYLE enmCommentStyle, PFNSCMCOMMENTENUMERATOR pfnCallback, void *pvUser);


/**
 * Include directive type.
 */
typedef enum SCMINCLUDEDIR
{
    kScmIncludeDir_Invalid = 0, /**< Constomary invalid enum value. */
    kScmIncludeDir_Quoted,      /**< \#include \"filename.h\" */
    kScmIncludeDir_Bracketed,   /**< \#include \<filename.h\> */
    kScmIncludeDir_Macro,       /**< \#include MACRO_H */
    kScmIncludeDir_End          /**< End of valid enum values. */
} SCMINCLUDEDIR;

SCMINCLUDEDIR ScmMaybeParseCIncludeLine(PSCMRWSTATE pState, const char *pchLine, size_t cchLine,
                                        const char **ppchFilename, size_t *pcchFilename);

/**
 * Checks if the given character is a valid C identifier lead character.
 *
 * @returns true / false.
 * @param   ch                  The character to inspect.
 * @sa      vbcppIsCIdentifierLeadChar
 */
DECLINLINE(bool) ScmIsCIdentifierLeadChar(char ch)
{
    return RT_C_IS_ALPHA(ch)
        || ch == '_';
}


/**
 * Checks if the given character is a valid C identifier character.
 *
 * @returns true / false.
 * @param   ch                  The character to inspect.
 * @sa      vbcppIsCIdentifierChar
 */
DECLINLINE(bool) ScmIsCIdentifierChar(char ch)
{
    return RT_C_IS_ALNUM(ch)
        || ch == '_';
}


/** @} */


/** @name Rewriters
 * @{ */

/**
 * Rewriter state.
 */
typedef struct SCMRWSTATE
{
    /** The filename.  */
    const char         *pszFilename;
    /** Set after the printing the first verbose message about a file under
     *  rewrite. */
    bool                fFirst;
    /** Set if the file requires manual repair. */
    bool                fNeedsManualRepair;
    /** Cached ScmSvnIsInWorkingCopy response. 0 indicates not known, 1 means it
     * is in WC, -1 means it doesn't. */
    int8_t              fIsInSvnWorkingCopy;
    /** The number of SVN property changes. */
    size_t              cSvnPropChanges;
    /** Pointer to an array of SVN property changes. */
    struct SCMSVNPROP  *paSvnPropChanges;
    /** For error propagation. */
    int32_t             rc;
} SCMRWSTATE;

/**
 * A rewriter.
 *
 * This works like a stream editor, reading @a pIn, modifying it and writing it
 * to @a pOut.
 *
 * @returns true if any changes were made, false if not.
 * @param   pIn                 The input stream.
 * @param   pOut                The output stream.
 * @param   pSettings           The settings.
 */
typedef bool FNSCMREWRITER(PSCMRWSTATE pState, PSCMSTREAM pIn, PSCMSTREAM pOut, PCSCMSETTINGSBASE pSettings);
/** Pointer to a rewriter method. */
typedef FNSCMREWRITER *PFNSCMREWRITER;

FNSCMREWRITER rewrite_StripTrailingBlanks;
FNSCMREWRITER rewrite_ExpandTabs;
FNSCMREWRITER rewrite_ForceNativeEol;
FNSCMREWRITER rewrite_ForceLF;
FNSCMREWRITER rewrite_ForceCRLF;
FNSCMREWRITER rewrite_AdjustTrailingLines;
FNSCMREWRITER rewrite_SvnNoExecutable;
FNSCMREWRITER rewrite_SvnNoKeywords;
FNSCMREWRITER rewrite_SvnNoEolStyle;
FNSCMREWRITER rewrite_SvnBinary;
FNSCMREWRITER rewrite_SvnKeywords;
FNSCMREWRITER rewrite_SvnSyncProcess;
FNSCMREWRITER rewrite_UnicodeChecks;
FNSCMREWRITER rewrite_PageChecks;
FNSCMREWRITER rewrite_ForceHrcVrcInsteadOfRc;
FNSCMREWRITER rewrite_Copyright_CstyleComment;
FNSCMREWRITER rewrite_Copyright_HashComment;
FNSCMREWRITER rewrite_Copyright_PythonComment;
FNSCMREWRITER rewrite_Copyright_RemComment;
FNSCMREWRITER rewrite_Copyright_SemicolonComment;
FNSCMREWRITER rewrite_Copyright_SqlComment;
FNSCMREWRITER rewrite_Copyright_TickComment;
FNSCMREWRITER rewrite_Copyright_XmlComment;
FNSCMREWRITER rewrite_Makefile_kup;
FNSCMREWRITER rewrite_Makefile_kmk;
FNSCMREWRITER rewrite_FixFlowerBoxMarkers;
FNSCMREWRITER rewrite_Fix_C_and_CPP_Todos;
FNSCMREWRITER rewrite_Fix_Err_H;
FNSCMREWRITER rewrite_FixHeaderGuards;
FNSCMREWRITER rewrite_C_and_CPP;

/**
 * Rewriter configuration.
 */
typedef struct SCMREWRITERCFG
{
    /** The rewriter function. */
    PFNSCMREWRITER  pfnRewriter;
    /** The name of the rewriter. */
    const char     *pszName;
} SCMREWRITERCFG;
/** Pointer to a const rewriter config. */
typedef SCMREWRITERCFG const *PCSCMREWRITERCFG;

/** @}  */


/** @name Settings
 * @{ */

/**
 * Configuration entry.
 */
typedef struct SCMCFGENTRY
{
    /** Number of rewriters. */
    size_t                  cRewriters;
    /** Pointer to an array of rewriters. */
    PCSCMREWRITERCFG const *paRewriters;
    /** Set if the entry handles binaries.  */
    bool                    fBinary;
    /** File pattern (simple).  */
    const char             *pszFilePattern;
    /** Name (for treat as).  */
    const char             *pszName;
} SCMCFGENTRY;
typedef SCMCFGENTRY *PSCMCFGENTRY;
typedef SCMCFGENTRY const *PCSCMCFGENTRY;


/** License update options. */
typedef enum SCMLICENSE
{
    kScmLicense_LeaveAlone = 0,     /**< Leave it alone. */
    kScmLicense_OseGpl,             /**< VBox OSE GPL if public. */
    kScmLicense_OseDualGplCddl,     /**< VBox OSE dual GPL & CDDL if public. */
    kScmLicense_OseCddl,            /**< VBox OSE CDDL if public. */
    kScmLicense_Lgpl,               /**< LGPL if public. */
    kScmLicense_Mit,                /**< MIT if public. */
    kScmLicense_BasedOnMit,         /**< Copyright us but based on someone else's MIT. */
    kScmLicense_End
} SCMLICENSE;

/**
 * Source Code Massager Settings.
 */
typedef struct SCMSETTINGSBASE
{
    bool            fConvertEol;
    bool            fConvertTabs;
    bool            fForceFinalEol;
    bool            fForceTrailingLine;
    bool            fStripTrailingBlanks;
    bool            fStripTrailingLines;

    /** Whether to fix C/C++ flower box section markers. */
    bool            fFixFlowerBoxMarkers;
    /** The minimum number of blank lines we want before flowerbox markers. */
    uint8_t         cMinBlankLinesBeforeFlowerBoxMakers;

    /** Whether to fix C/C++ header guards and \#pragma once directives. */
    bool            fFixHeaderGuards;
    /** Whether to include a pragma once statement with the header guard. */
    bool            fPragmaOnce;
    /** Whether to fix the \#endif part of a header guard. */
    bool            fFixHeaderGuardEndif;
    /** Whether to add a comment on the \#endif part of the header guard. */
    bool            fEndifGuardComment;
    /** The guard name prefix.   */
    char           *pszGuardPrefix;
    /** Header guards should be normalized using prefix and this directory.
     * When NULL the guard identifiers found in the header is preserved. */
    char           *pszGuardRelativeToDir;

    /** Whether to fix C/C++ todos. */
    bool            fFixTodos;
    /** Whether to fix C/C++ err.h/errcore.h usage. */
    bool            fFixErrH;
    /** No PAGE_SIZE, PAGE_SHIFT, PAGE_OFFSET_MASK allowed in C/C++, only the GUEST_
     * or HOST_ prefixed versions. */
    bool            fOnlyGuestHostPage;
    /** No ASMMemIsZeroPage or ASMMemZeroPage calls allowed (C/C++). */
    bool            fNoASMMemPageUse;
    /** No rc declarations allowed, only hrc or vrc depending on the result type. */
    bool            fOnlyHrcVrcInsteadOfRc;

    /** Update the copyright year. */
    bool            fUpdateCopyrightYear;
    /** Only external copyright holders. */
    bool            fExternalCopyright;
    /** Whether there should be a LGPL disclaimer. */
    bool            fLgplDisclaimer;
    /** How to update the license. */
    SCMLICENSE      enmUpdateLicense;

    /** Only process files that are part of a SVN working copy. */
    bool            fOnlySvnFiles;
    /** Only recurse into directories containing an .svn dir.  */
    bool            fOnlySvnDirs;
    /** Set svn:eol-style if missing or incorrect. */
    bool            fSetSvnEol;
    /** Set svn:executable according to type (unusually this means deleting it). */
    bool            fSetSvnExecutable;
    /** Set svn:keyword if completely or partially missing. */
    bool            fSetSvnKeywords;
    /** Skip checking svn:sync-process. */
    bool            fSkipSvnSyncProcess;
    /** Skip the unicode checks. */
    bool            fSkipUnicodeChecks;
    /** Tab size. */
    uint8_t         cchTab;
    /** Optimal source code width. */
    uint8_t         cchWidth;
    /** Free the treat as structure. */
    bool            fFreeTreatAs;
    /** Prematched config entry. */
    PCSCMCFGENTRY   pTreatAs;
    /** Only consider files matching these patterns.  This is only applied to the
     *  base names. */
    char           *pszFilterFiles;
    /** Filter out files matching the following patterns.  This is applied to base
     *  names as well as the absolute paths.  */
    char           *pszFilterOutFiles;
    /** Filter out directories matching the following patterns.  This is applied
     *  to base names as well as the absolute paths.  All absolute paths ends with a
     *  slash and dot ("/.").  */
    char           *pszFilterOutDirs;
} SCMSETTINGSBASE;
/** Pointer to massager settings. */
typedef SCMSETTINGSBASE *PSCMSETTINGSBASE;

/**
 * File/dir pattern + options.
 */
typedef struct SCMPATRNOPTPAIR
{
    char *pszPattern;
    char *pszOptions;
    char *pszRelativeTo;
    bool  fMultiPattern;
} SCMPATRNOPTPAIR;
/** Pointer to a pattern + option pair. */
typedef SCMPATRNOPTPAIR *PSCMPATRNOPTPAIR;


/** Pointer to a settings set. */
typedef struct SCMSETTINGS *PSCMSETTINGS;
/**
 * Settings set.
 *
 * This structure is constructed from the command line arguments or any
 * .scm-settings file found in a directory we recurse into.  When recursing in
 * and out of a directory, we push and pop a settings set for it.
 *
 * The .scm-settings file has two kinds of setttings, first there are the
 * unqualified base settings and then there are the settings which applies to a
 * set of files or directories.  The former are lines with command line options.
 * For the latter, the options are preceded by a string pattern and a colon.
 * The pattern specifies which files (and/or directories) the options applies
 * to.
 *
 * We parse the base options into the Base member and put the others into the
 * paPairs array.
 */
typedef struct SCMSETTINGS
{
    /** Pointer to the setting file below us in the stack. */
    PSCMSETTINGS        pDown;
    /** Pointer to the setting file above us in the stack. */
    PSCMSETTINGS        pUp;
    /** File/dir patterns and their options. */
    PSCMPATRNOPTPAIR    paPairs;
    /** The number of entires in paPairs. */
    uint32_t            cPairs;
    /** The base settings that was read out of the file. */
    SCMSETTINGSBASE     Base;
} SCMSETTINGS;
/** Pointer to a const settings set. */
typedef SCMSETTINGS const *PCSCMSETTINGS;

/** @} */


void ScmVerboseBanner(PSCMRWSTATE pState, int iLevel);
void ScmVerbose(PSCMRWSTATE pState, int iLevel, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
bool ScmError(PSCMRWSTATE pState, int rc, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
bool ScmFixManually(PSCMRWSTATE pState, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3);

extern const char g_szTabSpaces[16+1];
extern const char g_szAsterisks[255+1];
extern const char g_szSpaces[255+1];
extern uint32_t g_uYear;

RT_C_DECLS_END

#endif /* !VBOX_INCLUDED_SRC_bldprogs_scm_h */