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

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:

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.