Table of Contents
OFP CfgCheck
OFP Forum, OFP Home, OFP File Formats, OFP Tools, OFP Missions, OFP 3D Modeling, OFP Terrain
Operation Flashpoint (OFP) aka ArmA: Cold War Assault (CWA)
CfgCheck checks OFP configs for syntactic errors and a simple semantic check (double entries).
Overview
CfgCheck is excellent tool to keep your config.cpp files in order, it will hunt down and report all errors in there which you can so easily overlook while editing, it will intend it correctly to it looks organized and beautiful source code.
PMC will run all its config.cpp files through this util before release to maintain good cpp files in the code and look.
Usage
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
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
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 and *.cfg files.
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
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
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
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 Info
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
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.
Notes
Author:
vektorboson (Lukas Pinkowski), vektorboson@gmx.de
Credits:
Mike Andrew for file format descriptions
Download from here.