cfgcheck
Checks OFP configs for syntactic errors and a simple
semantic check (double entries).
Usage:
cfgcheck [-bin] [-cpponly] [-nocpp] [-b] [-tabs] [-cc] [-clean] [-o OUTFILE] [-mod=LIST] FILENAME
Runs the file FILENAME through a preprocessor, then parses the result.
The simpliest method to run it, drag a config.cpp and drop it on the
cfgcheck.exe. Another method is to use it directly from the command line.
Options in square brackets are optional, some options exclude other options.
FILENAME may also be a directory; in this case the directory's config.cpp
is checked.
Use at your own risk!
Command Line Parameters
-cpponly: runs the file only through the preprocessor
(excludes -nocpp)
-nocpp: doesn't run the file through the preprocessor
(excludes -cpponly)
-b: beautifies the input file
-o OUTFILE: output from -cpponly or -b goes into OUTFILE
-mod=list: similar to OFP's mod command line option
-tabs: use tabs instead of spaces (when using -b)
-cc: comment at end of class declaration (when using -b)
-clean: in case of an error, don't write cpperror.txt
-bin: binarize config; writes either FILENAME.bin or OUTFILE
HOW IT WORKS
CfgCheck takes the input file and runs the Preprocessor over it, in the
same way as OFP does with text mission.sqm, config.cpp, resource.cpp,
description.ext, *.sqf, *.cfg
It expands all Macros along with their arguments, includes any files
specified by #include and builds the "real" file, which is then
checked for errors.
MACROS
There are basically three types of macros: Valueless macros, simple
macros, macros with arguments.
Valueless macros are of the form:
#define MACRONAME
If MACRONAME is found in the file, it is replaced by "nothing"; those
macros are rather used for conditional macros like #ifdef and #ifndef.
Simple Macro:
#define MACRONAME value
If MACRONAME is found in the file, it is replaced by value.
Macros with arguments:
#define MACRONAME(x, y, z) x loves y, but not z.
If a parameter name is found in the value text, then it is replaced
by the corresponding parameter.
#define VALUE(x) x
ammo = VALUE(10); // expands to: ammo = 10;
But there is also stringification and concatenation:
#define STRING(x) displayName = #x;
STRING(M1A1) // expands to: displayName = "M1A1";
#define PROXY(x) class Proxy##x { model = #x; };
PROXY(ak47) // expands to: class Proxyak47 { model = "ak47"; };
PREDEFINED MACROS
CfgCheck predefines right now exactly one macro: __CFGCHECK__ - that is
two underlines followed by CFGCHECK (case sensitive!) followed by two
underlines.
You can use this to hide sections from OFP, or vice versa (use #ifdef and
#ifndef). This can be useful when using #include, as CfgCheck interprets
#include in a special manner. One example is, you are using #include to
separate parts of the config into different files. When running CfgCheck on
the config.cpp, you'll get probably an error (file not found) or you will be
scanning the included files in the PBO in your addons-directory instead of
the local file. Here you use the following workaround:
#ifdef __CFGCHECK__
// this is for CfgCheck
#include "weapons.hpp"
#include "ammo.hpp"
#include "vehicles.hpp"
#else
// this is for OFP
#include <myaddon\weapons.hpp>
#include <myaddon\ammo.hpp>
#include <myaddon\vehicles.hpp>
#endif
FILE INCLUSION (INCLUDES)
File inclusion is done with #include; there are two types of includes:
#include "path" // relative inclusion
#include <path> // system inclusion
I don't think OFP makes a difference between the two, but I think it
is better to make a difference. You'll see the former in the commented
config.
So if you're writing a Mod config, then use the former; if you want to
include from somewhere of the OFP directory or from a PBO, then use
the latter.
#include "CfgMoves.hpp"
// includes CfgMoves.hpp from the same directory
// as the "current" file
#include <myaddon\res.hpp>
// include from MYADDON.pbo file res.hpp
#include <mymod\inc\res.hpp>
// include from the MYMOD mod directory
// the file RES.HPP in the INC-directory
BUGS and other information
OFP allows variable definitions like this:
displayName = ;
sound[] = {,0,0};
These are interpreted as empty strings "" by OFP.
CfgCheck doesn't support those (yet?). Always write
displayName = "";
sound[] = {"",0,0};
This is clear.
OFP allows to omit the semicolon ';' after a variable or the closing
brace '}' of a class, when it is followed by a newline. CfgCheck does
not, it is very strict about the semicolon, always put it at the end
of a declaration or class.
CfgCheck only supports UTF-8 character encoding, if you get an
UTF8 error, then you have three possibilities:
- use another tool
- change the offending character(s)
- outsource the offending string to stringtable.csv
enums
An enum or enumeration is a collection of identifiers that are synonyms
for numbers. Example:
enum
{
ManPosDead,
ManPosFoo,
ManPosBar
}
Basically ManPosDead is a synonym for 0 and ManPosFoo for 1, a.s.o. You need
these enum-constants in the MOD\bin\config.cpp, if you want to use a cpp in
your Mod instead of a binary config. Please look into the commented config by
BIS and search for enum and copy every enum declaration over to your
config.cpp. CfgCheck knows about enum, enums are parsed and checked for
errors, but they do not influence the output config in any way (yet).
So for beautified configs, you have to copy over the enum declaration.
I'll research further in what way to handle enum correctly.
Author:
Lukas Pinkowski, vektorboson@gmx.de
Credits:
Mike Andrew for file format descriptions
Version:
1.14
BUGS:
Enum not handled correctly, Errorline number is sometimes one/two line
numbers bigger, no parameter to disable VFS (check in oxygen-directory),
Macro errors, cfgcheck doesn't work properly on resource.cpp from
Binarize
Date:
June 01, 2006
History:
1.14
- Fixed: Bug in Preprocessor with Macros and TABS
1.13
- Added: CfgCheck predefines the macro __CFGCHECK__
1.12
- Fixed: Required space after #define, but did not accept tabulator
1.11
- Fixed: Uncaught exception for too big integer values
1.10
- Fixed: missing 0x00000000 at end of file for binary configs.
1.9
- Added: -bin binarize config
1.8
- Added: -clean command line parameter
1.7
- Changed: Improved internal config-representation
- Added: -tabs command line parameter
- Added: -cc command line parameter
- Fixed: Nested arrays crash
- Fixed: config was parsed but not saved after enum
1.6
- Added: If parameter is a directory, directory is looked for config.cpp
- Fixed: writing 0x1a with include caused parser to stop prematurely!
- Fixed: documentation on include for addons
1.5
- Fixed: crash if no character after #endif
1.4
- Fixed: #include didn't work, if path of input file was just filename+ext
1.3
- Added: support for compressed PBOs
1.2
- Fixed: Access Violation for array[] = { value, };
- Changed: cpperror.txt is written in same directory as cfgcheck.exe
1.1
- Added: uncompressed PBO support
- Added: parses enum
- Fixed: Error if included file doesn't end with a newline
- Fixed: Preprocessed file did not end with EOF
- Fixed: Diverse crashes
1.0
initial release
Page generated by Ddoc. (C) 2005-2006 Lukas Pinkowski, vektorboson@gmx.de