64 void process_value_enums(FieldSpecMap::const_iterator itr, ostream& ost_hpp, ostream& ost_cpp);
 
   65 const string& 
mkel(
const string& base, 
const string& compon, 
string& where);
 
   73    const string ident_set(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789");
 
   85    unique_ptr<ofstream> os(
new ofstream(target.c_str()));
 
   88       cerr << 
"Error opening file \'" << target << 
'\'';
 
   90          cerr << 
" (" << strerror(errno) << 
')';
 
  100 const string& 
mkel(
const string& base, 
const string& compon, 
string& where)
 
  103    ostr << base << 
'/' << compon;
 
  104    return where = ostr.str();
 
  108 const string& 
filepart(
const string& source, 
string& where)
 
  110    string::size_type pos(source.find_last_of(
'/'));
 
  111    return pos == string::npos ? where = source : where = source.substr(pos + 1);
 
  120       cerr << 
"No fix header element found in " << 
shortName << endl;
 
  124    string major, minor, revision(
"0"), type(
"FIX");
 
  126    if (!fix->GetAttr(
"major", major) || !fix->GetAttr(
"minor", minor))
 
  128       cerr << 
"Missing required attributes (major/minor) from fix header in " << 
shortName << endl;
 
  132    if (!fix->GetAttr(
"revision", revision))
 
  133       fix->GetAttr(
"servicepack", revision);
 
  134    fix->GetAttr(
"type", type);
 
  137    ctxt.
_version = stoi(major) * 1000 + stoi(minor) * 100 + stoi(revision);
 
  138    if (type == 
"FIX" && ctxt.
_version < 4000)
 
  140       cerr << 
"Unsupported FIX version " << ctxt.
_version << 
" from fix header in " << 
shortName << endl;
 
  152    ostr << type << 
'.' << major << 
'.' << minor;
 
  166       fts.
set(field, FieldTrait::suppress);  
 
  168       fts.
set(field, FieldTrait::automatic);
 
  169       fts.
clear(field, FieldTrait::mandatory);  
 
  179    if (FieldTrait::get_type_string(itr->second._ftype, typestr).empty())
 
  181    typestr.insert(0, 
"const ");
 
  184    ost_cpp << typestr << itr->second._name << 
"_realm[]  " << endl << 
spacer << 
"{ ";
 
  186    for (RealmMap::const_iterator ditr(itr->second._dvals->begin()); ditr != itr->second._dvals->end(); ++ditr)
 
  190       ost_cpp << *ditr->first;
 
  191       string transdesc(ditr->second);
 
  194       ost_hpp << typestr << itr->second._name << 
'_';
 
  195       if (ditr->first->is_range())
 
  196          ost_hpp << (cnt == 0 ? 
"lower" : 
"upper");
 
  197       else if (transdesc.empty())
 
  198          ost_hpp << *ditr->first;
 
  200          ost_hpp << transdesc;
 
  201       ost_hpp << 
'(' << *ditr->first << 
");" << endl;
 
  204    ost_hpp << 
"const size_t " << itr->second._name << 
"_realm_els(" << itr->second._dvals->size() << 
");" << endl;
 
  205    ost_cpp << 
" };" << endl;
 
  207    ost_cpp << 
"const char *" << itr->second._name << 
"_descriptions[]  " << endl << spacer << 
"{ ";
 
  209    for (RealmMap::const_iterator ditr(itr->second._dvals->begin()); ditr != itr->second._dvals->end(); ++ditr)
 
  213       ost_cpp << 
'"' << ditr->second << 
'"';
 
  216    ost_cpp << 
" };" << endl;
 
  223    unsigned processed(0);
 
  225    if (xt->
find(where, flist))
 
  227       for(
const auto *pp : flist)
 
  229          string fname, required;
 
  230          if (pp->GetAttr(
"name", fname) && pp->GetAttr(
"required", required))
 
  232             FieldToNumMap::const_iterator ftonItr(ftonSpec.find(fname));
 
  233             FieldSpecMap::iterator fs_itr;
 
  234             if (ftonItr == ftonSpec.end() || (fs_itr = fspec.find(ftonItr->second)) == fspec.end())
 
  236                cerr << 
shortName << 
':' << 
recover_line(*pp) << 
": error: Field element missing required attributes" << endl;
 
  242             unsigned compidx(pp->GetAttr(
"component", compname) ? 
lookup_component(compon, compname) : 0);
 
  245             if (!fts.
add(
FieldTrait(fs_itr->first, fs_itr->second._ftype, pp->GetSubIdx(), required == 
"Y", 
false, compidx)))
 
  248                   cerr << 
shortName << 
':' << 
recover_line(*pp) << 
": warning: Could not add trait object '" << fname << 
"' (duplicate ?)" << endl;
 
  255                fs_itr->second.set_used();
 
  260             cerr << 
shortName << 
':' << 
recover_line(*pp) << 
": error: Field element missing required attributes" << endl;
 
  272    ostringstream result;
 
  273    for (
const auto& cc : from)
 
  274       result << uppercase << hex << setw(2) << setfill('0') << static_cast<unsigned short>(cc);
 
  275    return "FIX8_" + result.str() + 
'_';
 
  281    for (
const auto& pp : mspec)
 
  284       for (
const auto& ii : pp.second._fields.get_presence())
 
  296    for (
const auto& pp : gm)
 
  299       for (
const auto& ii : pp.second._fields.get_presence())
 
  306       if (!pp.second._groups.empty())
 
  314    for (
const auto& pp : globmap)
 
  315       for (
const auto& ii : pp.second)
 
  323    um.
setdesc(
"f8c -- compile FIX xml schema");
 
  324    um.
add(
'o', 
"odir <dir>", 
"output target directory (default ./)");
 
  325    um.
add(
'p', 
"prefix <prefix>", 
"output filename prefix (default Myfix)");
 
  326    um.
add(
'H', 
"pch <filename>", 
"use specified precompiled header name for Windows (default none)");
 
  327    um.
add(
'd', 
"dump", 
"dump 1st pass parsed source xml file, exit");
 
  328    um.
add(
'e', 
"extension", 
"Generate with .cxx/.hxx extensions (default .cpp/.hpp)");
 
  329    um.
add(
'f', 
"fields", 
"generate code for all defined fields even if they are not used in any message (default no)");
 
  330    um.
add(
'F', 
"xfields", 
"specify additional fields with associated messages (see documentation for details)");
 
  331    um.
add(
'h', 
"help", 
"help, this screen");
 
  332    um.
add(
'i', 
"ignore", 
"ignore errors, attempt to generate code anyhow (default no)");
 
  333    um.
add(
'k', 
"keep", 
"retain generated temporaries even if there are errors (.*.tmp)");
 
  334    um.
add(
'v', 
"version", 
"print version, exit");
 
  335    um.
add(
'I', 
"info", 
"print package info, exit");
 
  336    um.
add(
's', 
"second", 
"2nd pass only, no precompile (default both)");
 
  337    um.
add(
'S', 
"noshared", 
"Treat every group as unique and expose all static traits. Do not share metadata in message classes (default shared)");
 
  338    um.
add(
'N', 
"nounique", 
"do not enforce unique field parsing (default false)");
 
  339    um.
add(
'R', 
"norealm", 
"do not generate realm constructed field instantiators (default false)");
 
  340    um.
add(
'W', 
"nowarn", 
"suppress warning messages (default false)");
 
  341    um.
add(
'C', 
"nocheck", 
"do not embed version checking in generated code (default false)");
 
  342    um.
add(
'D', 
"defaulted", 
"do not generate default router bodies. Application must provide all router definitions (default false)");
 
  343    um.
add(
'U', 
"noconst", 
"Generate non-const Router method declarations (default false, const)");
 
  344    um.
add(
'u', 
"unused", 
"Report unused fields, requires verbose option (default false)");
 
  345    um.
add(
'r', 
"retain", 
"retain 1st pass code (default delete)");
 
  346    um.
add(
'b', 
"binary", 
"print binary/ABI details, exit");
 
  347    um.
add(
'P', 
"incpath", 
"prefix system include path with \"fix8\" in generated compilation units (default yes)");
 
  348    um.
add(
'c', 
"classes <server|client>", 
"generate user session classes (default neither)");
 
  349    um.
add(
't', 
"tabwidth", 
"tabwidth for generated code (default 3 spaces)");
 
  350    um.
add(
'x', 
"fixt <file>", 
"For FIXT hosted transports or for FIX5.0 and above, the input FIXT schema file");
 
  351    um.
add(
'V', 
"verbose", 
"be more verbose when processing");
 
  352    um.
add(
'n', 
"namespace <ns>", 
"namespace to place generated code in (default FIXMmvv e.g. FIX4400)");
 
  354    um.
add(
"@f8c -p Texfix -n TEX myfix.xml");
 
  355    um.
add(
"@f8c -rp Texfix -n TEX -x ../schema/FIXT11.xml myfix.xml");
 
  356    um.
add(
"@f8c -p Texfix -n TEX -c client -x ../schema/FIXT11.xml myfix.xml");
 
  357    um.
add(
"@f8c -p Texfix -n TEX -c client -x ../schema/FIXT11.xml myfix.xml -F \"<field number='9999' name='SampleUserField' type='STRING' messages='NewOrderSingle:Y ExecutionReport:Y OrderCancelRequest:N' />");
 
  364    if (FieldTrait::is_int(ftype))
 
  366    if (FieldTrait::is_char(ftype))
 
  368    if (FieldTrait::is_float(ftype))
 
  370    if (FieldTrait::is_string(ftype))
 
  381    ptim = localtime (&now);
 
  384    localtime_r(&now, &tim);
 
  389    ostr << setw(2) << (ptim->tm_year - 100);
 
  396    static const vector<string> incfiles
 
  412    to << 
"// f8 includes" << endl;
 
  413    for (
const auto& pp : incfiles)
 
  414       to << 
"#include " << (
incpath ? 
"<fix8/" : 
"<") << pp << 
'>' << endl;
 
  420    os << 
"Name:" << what.
_name;
 
  425    os << 
" isadmin:" << boolalpha << what.
_is_admin << endl;
 
  426    os << 
"Fields:" << endl << what.
_fields;
 
  427    for (
const auto& pp : what.
_groups)
 
  428       os << 
"Group (" << pp.first << 
"): " << endl << pp.second << endl;
 
const unsigned short Common_CheckSum(10)
 
void clear(const unsigned short field, Presence::const_iterator &itr, FieldTrait::TraitTypes type=FieldTrait::present)
 
const string & mkel(const string &base, const string &compon, string &where)
 
F8API std::string & InPlaceReplaceInSet(const std::string &iset, std::string &src, const char repl='_')
 
std::map< std::string, const XmlElement * > Components
 
bool add(const char sw, const std::string &lsw, const std::string &help)
 
f8c internal message representation. 
 
std::map< unsigned, struct MessageSpec > GroupMap
 
string bintoaschex(const string &from)
 
const string & filepart(const string &source, string &where)
 
std::ostream & operator<<(std::ostream &os, const GroupBase &what)
 
ostream * open_ofile(const string &odir, const string &fname, string &target)
 
int recover_line(const XmlElement &xf)
 
unsigned lookup_component(const Components &compon, const f8String &name)
 
void process_special_traits(const unsigned short field, FieldTraits &fts)
 
f8c character realm type. 
 
Used for static trait interrogation. 
 
void generate_includes(ostream &to)
 
int load_messages(XmlElement &xf, MessageSpecMap &mspec, const FieldToNumMap &ftonSpec, FieldSpecMap &fspec)
 
std::map< unsigned, struct FieldSpec > FieldSpecMap
 
void setdesc(const std::string &desc)
 
A simple xml parser with Xpath style lookup. 
 
void print(std::ostream &os) const 
 
f8c range or set domain realm. 
 
int process(XmlElement &xf, Ctxt &ctxt)
 
std::multiset< const FieldTrait *, FieldTrait::PosCompare > FieldTraitOrder
 
const unsigned short Common_MsgType(35)
 
void process_value_enums(FieldSpecMap::const_iterator itr, ostream &ost_hpp, ostream &ost_cpp)
 
std::set< const XmlElement *, EntityOrderComp > XmlSet
 
std::map< std::string, unsigned > FieldToNumMap
 
const unsigned short Common_BodyLength(9)
 
std::map< const std::string, MessageSpec > MessageSpecMap
 
const unsigned short Common_BeginString(8)
 
F8API std::string & CheckAddTrailingSlash(std::string &source)
 
std::map< unsigned, CommonGroups > CommonGroupMap
 
bool add(const FieldTrait &what)
 
A collection of FieldTraits for a message. Which fields are required, which are present. 
 
int load_fix_version(XmlElement &xf, Ctxt &ctxt)
 
int load_fields(XmlElement &xf, FieldSpecMap &fspec)
 
bool exist(const std::string &fname)
 
F8API const XmlElement * find(const std::string &what, const std::string *atag=nullptr, const std::string *aval=nullptr, const char delim='/') const 
 
int process_message_fields(const std::string &where, XmlElement *xt, FieldTraits &fts, const FieldToNumMap &ftonSpec, FieldSpecMap &fspec, const Components &compon)
 
Convenient program help/usage wrapper. Generates a standardised usage message. 
 
void set(const unsigned short field, Presence::const_iterator &itr, FieldTrait::TraitTypes type)
 
void process_ordering(MessageSpecMap &mspec)
 
void process_message_group_ordering(const GroupMap &gm)
 
void process_group_ordering(const CommonGroupMap &gm)