/*
* DEBUG: none Generate squid.conf.default and cf_parser.cci
* AUTHOR: Max Okumoto
+ * AUTHOR: Francesco Chemolli
+ * AUTHOR: Amos Jeffries
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
* ----------------------------------------------------------
#include <cstring>
#include <fstream>
#include <iostream>
+#include <list>
#include "cf_gen_defines.cci"
sEXIT
};
-// TODO: inherit all these from link lists.
+typedef std::list<std::string> LineList;
+typedef std::list<std::string> TypeDepList;
+typedef std::list<std::string> EntryAliasList;
-class Line
+class DefaultValues
{
public:
- Line(const char *str) : data(str), next(NULL) {}
- ~Line() {}
+ DefaultValues() : preset(), if_none(), docs() {}
+ ~DefaultValues() {}
- std::string data;
- Line *next;
-};
+ /// Default config lines to be defined before parsing the config files.
+ LineList preset;
-class EntryAlias
-{
-public:
- EntryAlias(const char *str) : name(str), next(NULL) {}
- ~EntryAlias() {}
+ /// Default config lines to parse if the directive has no prior settings.
+ /// This is mutually exclusive with preset values.
+ /// An error will be printed during build if they clash.
+ LineList if_none;
- std::string name;
- EntryAlias *next;
+ /// Text description to use in documentation for the default.
+ /// If unset the preset or if-none values will be displayed.
+ LineList docs;
};
class Entry
{
public:
Entry(const char *str) :
- name(str), alias(), type(), loc(),
- default_value(), default_if_none(),
- comment(), ifdef(), doc(), nocomment(),
- next(NULL) {}
+ name(str), alias(),type(), loc(),
+ defaults(), comment(), ifdef(), doc(), nocomment(),
+ array_flag(0) {}
~Entry() {}
std::string name;
- EntryAlias *alias;
+ EntryAliasList alias;
std::string type;
std::string loc;
- std::string default_value;
- Line *default_if_none;
+ DefaultValues defaults;
std::string comment;
std::string ifdef;
- Line *doc;
- Line *nocomment;
+ LineList doc;
+ LineList nocomment;
int array_flag;
- Entry *next;
-};
+ void genParse(std::ostream &fout) const;
-class TypeDep
-{
-public:
- TypeDep(const char *str) : name(str), next(NULL) {}
- ~TypeDep() {}
-
- std::string name;
- TypeDep *next;
+private:
+ void genParseAlias(const std::string &, std::ostream &) const;
};
+typedef std::list<class Entry> EntryList;
+
class Type
{
public:
- Type(const char *str) : name(str), next(NULL) {}
+ Type(const char *str) : name(str) {}
~Type() {}
std::string name;
- TypeDep *depend;
- Type *next;
+ TypeDepList depend;
};
-static const char WS[] = " \t\n";
-static int gen_default(Entry *, std::ostream &);
-static void gen_parse(Entry *, std::ostream &);
-static void gen_parse_entry(Entry *entry, std::ostream&);
-static void gen_parse_alias(const std::string &, EntryAlias *, Entry *, std::ostream &);
-static void gen_dump(Entry *, std::ostream&);
-static void gen_free(Entry *, std::ostream&);
-static void gen_conf(Entry *, std::ostream&, bool verbose_output);
-static void gen_default_if_none(Entry *, std::ostream&);
-
-static void
-lineAdd(Line ** L, const char *str)
-{
- assert(str);
+typedef std::list<class Type> TypeList;
- while (*L)
- L = &(*L)->next;
-
- *L = new Line(str);
-}
+static const char WS[] = " \t\n";
+static int gen_default(const EntryList &, std::ostream &);
+static void gen_parse(const EntryList &, std::ostream &);
+static void gen_dump(const EntryList &, std::ostream&);
+static void gen_free(const EntryList &, std::ostream&);
+static void gen_conf(const EntryList &, std::ostream&, bool verbose_output);
+static void gen_default_if_none(const EntryList &, std::ostream&);
static void
-checkDepend(const std::string &directive, const char *name, const Type *types, const Entry *entries)
+checkDepend(const std::string &directive, const char *name, const TypeList &types, const EntryList &entries)
{
- const Type *type;
- for (type = types; type; type = type->next) {
- const TypeDep *dep;
- if (type->name.compare(name) != 0)
+ for (TypeList::const_iterator t = types.begin(); t != types.end(); ++t) {
+ if (t->name.compare(name) != 0)
continue;
- for (dep = type->depend; dep; dep = dep->next) {
- const Entry *entry;
- for (entry = entries; entry; entry = entry->next) {
- if (entry->name.compare(dep->name) == 0)
+ for (TypeDepList::const_iterator dep = t->depend.begin(); dep != t->depend.end(); ++dep) {
+ EntryList::const_iterator entry = entries.begin();
+ for (; entry != entries.end(); ++entry) {
+ if (entry->name.compare(*dep) == 0)
break;
}
- if (!entry) {
- std::cerr << "ERROR: '" << directive << "' (" << name << ") depends on '" << dep->name << "'\n";
+ if (entry == entries.end()) {
+ std::cerr << "ERROR: '" << directive << "' (" << name << ") depends on '" << *dep << "'\n";
exit(1);
}
}
const char *conf_filename_short = _PATH_SQUID_CONF_SHORT;
const char *type_depend;
int linenum = 0;
- Entry *entries = NULL;
- Entry *curr = NULL;
- Type *types = NULL;
+ EntryList entries;
+ TypeList types;
enum State state;
int rc = 0;
char *ptr = NULL;
const char *dep;
if (!type || type[0] == '#')
continue;
- Type *t = new Type(type);
+ Type t(type);
while ((dep = strtok(NULL, WS)) != NULL) {
- TypeDep *d = new TypeDep(dep);
- d->next = t->depend;
- t->depend = d;
+ t.depend.push_front(dep);
}
- t->next = types;
- types = t;
+ types.push_front(t);
}
fp.close();
fp.clear(); // BSD does not reset flags in close().
exit(1);
}
- curr = new Entry(name);
+ entries.push_back(name);
- while ((aliasname = strtok(NULL, WS)) != NULL) {
- EntryAlias *alias = new EntryAlias(aliasname);
- alias->next = curr->alias;
- curr->alias = alias;
- }
+ while ((aliasname = strtok(NULL, WS)) != NULL)
+ entries.back().alias.push_front(aliasname);
state = s1;
} else if (!strcmp(buff, "EOF")) {
state = sEXIT;
} else if (!strcmp(buff, "COMMENT_START")) {
- curr = new Entry("comment");
- curr->loc = "none";
+ entries.push_back("comment");
+ entries.back().loc = "none";
state = sDOC;
} else {
std::cerr << "Error on line " << linenum << std::endl <<
break;
- case s1:
+ case s1: {
+ Entry &curr = entries.back();
if ((strlen(buff) == 0) || (!strncmp(buff, "#", 1))) {
/* ignore empty and comment lines */
while (isspace((unsigned char)*ptr))
ptr++;
- curr->comment = ptr;
+ curr.comment = ptr;
} else if (!strncmp(buff, "DEFAULT:", 8)) {
ptr = buff + 8;
while (isspace((unsigned char)*ptr))
ptr++;
- curr->default_value = ptr;
+ curr.defaults.preset.push_back(ptr);
} else if (!strncmp(buff, "DEFAULT_IF_NONE:", 16)) {
ptr = buff + 16;
while (isspace((unsigned char)*ptr))
ptr++;
- lineAdd(&curr->default_if_none, ptr);
+ curr.defaults.if_none.push_back(ptr);
+ } else if (!strncmp(buff, "DEFAULT_DOC:", 12)) {
+ ptr = buff + 12;
+
+ while (isspace((unsigned char)*ptr))
+ ptr++;
+
+ curr.defaults.docs.push_back(ptr);
} else if (!strncmp(buff, "LOC:", 4)) {
if ((ptr = strtok(buff + 4, WS)) == NULL) {
std::cerr << "Error on line " << linenum << std::endl;
exit(1);
}
- curr->loc = ptr;
+ curr.loc = ptr;
} else if (!strncmp(buff, "TYPE:", 5)) {
if ((ptr = strtok(buff + 5, WS)) == NULL) {
std::cerr << "Error on line " << linenum << std::endl;
/* hack to support arrays, rather than pointers */
if (0 == strcmp(ptr + strlen(ptr) - 2, "[]")) {
- curr->array_flag = 1;
+ curr.array_flag = 1;
*(ptr + strlen(ptr) - 2) = '\0';
}
- checkDepend(curr->name, ptr, types, entries);
- curr->type = ptr;
+ checkDepend(curr.name, ptr, types, entries);
+ curr.type = ptr;
} else if (!strncmp(buff, "IFDEF:", 6)) {
if ((ptr = strtok(buff + 6, WS)) == NULL) {
std::cerr << "Error on line " << linenum << std::endl;
exit(1);
}
- curr->ifdef = ptr;
+ curr.ifdef = ptr;
} else if (!strcmp(buff, "DOC_START")) {
state = sDOC;
} else if (!strcmp(buff, "DOC_NONE")) {
- /* add to list of entries */
- curr->next = entries;
- entries = curr;
state = sSTART;
} else {
std::cerr << "Error on line " << linenum << std::endl;
exit(1);
}
-
- break;
+ }
+ break;
case sDOC:
-
if (!strcmp(buff, "DOC_END") || !strcmp(buff, "COMMENT_END")) {
- Line *head = NULL;
- Line *line = curr->doc;
- /* reverse order of doc lines */
-
- while (line != NULL) {
- Line *tmp;
- tmp = line->next;
- line->next = head;
- head = line;
- line = tmp;
- }
-
- curr->doc = head;
- /* add to list of entries */
- curr->next = entries;
- entries = curr;
state = sSTART;
} else if (!strcmp(buff, "NOCOMMENT_START")) {
state = sNOCOMMENT;
} else { // if (buff != NULL) {
assert(buff != NULL);
- Line *line = new Line(buff);
- line->next = curr->doc;
- curr->doc = line;
+ entries.back().doc.push_back(buff);
}
-
break;
case sNOCOMMENT:
-
if (!strcmp(buff, "NOCOMMENT_END")) {
- Line *head = NULL;
- Line *line = curr->nocomment;
- /* reverse order of lines */
-
- while (line != NULL) {
- Line *tmp;
- tmp = line->next;
- line->next = head;
- head = line;
- line = tmp;
- }
-
- curr->nocomment = head;
state = sDOC;
} else { // if (buff != NULL) {
assert(buff != NULL);
- Line *line = new Line(buff);
- line->next = curr->nocomment;
- curr->nocomment = line;
+ entries.back().nocomment.push_back(buff);
}
-
break;
case sEXIT:
if (state != sEXIT) {
std::cerr << "Error: unexpected EOF\n";
exit(1);
- } else {
- /* reverse order of entries */
- Entry *head = NULL;
-
- while (entries != NULL) {
- Entry *tmp;
-
- tmp = entries->next;
- entries->next = head;
- head = entries;
- entries = tmp;
- }
-
- entries = head;
}
fp.close();
" * Abstract: This file contains routines used to configure the\n"
" * variables in the squid server.\n"
" */\n"
- "\n"
- "#include \"config.h\"\n"
"\n";
rc = gen_default(entries, fout);
}
static int
-gen_default(Entry * head, std::ostream &fout)
+gen_default(const EntryList &head, std::ostream &fout)
{
- Entry *entry;
int rc = 0;
- fout << "static void\n"
- "default_line(const char *s)\n"
- "{\n"
- "\tLOCAL_ARRAY(char, tmp_line, BUFSIZ);\n"
- "\txstrncpy(tmp_line, s, BUFSIZ);\n"
- "\txstrncpy(config_input_line, s, BUFSIZ);\n"
- "\tconfig_lineno++;\n"
- "\tparse_line(tmp_line);\n"
- "}\n";
- fout << "static void\n"
- "default_all(void)\n"
- "{\n"
- "\tcfg_filename = \"Default Configuration\";\n"
- "\tconfig_lineno = 0;\n";
-
- for (entry = head; entry != NULL; entry = entry->next) {
+ fout << "static void" << std::endl <<
+ "default_line(const char *s)" << std::endl <<
+ "{" << std::endl <<
+ " LOCAL_ARRAY(char, tmp_line, BUFSIZ);" << std::endl <<
+ " xstrncpy(tmp_line, s, BUFSIZ);" << std::endl <<
+ " xstrncpy(config_input_line, s, BUFSIZ);" << std::endl <<
+ " config_lineno++;" << std::endl <<
+ " parse_line(tmp_line);" << std::endl <<
+ "}" << std::endl << std::endl;
+ fout << "static void" << std::endl <<
+ "default_all(void)" << std::endl <<
+ "{" << std::endl <<
+ " cfg_filename = \"Default Configuration\";" << std::endl <<
+ " config_lineno = 0;" << std::endl;
+
+ for (EntryList::const_iterator entry = head.begin(); entry != head.end(); ++entry) {
assert(entry->name.size());
- assert(entry != entry->next);
if (!entry->name.compare("comment"))
continue;
continue;
}
- if (!entry->default_value.size() && entry->default_if_none == NULL) {
+ if (!entry->defaults.preset.size() && entry->defaults.if_none.empty()) {
std::cerr << "NO DEFAULT FOR " << entry->name << std::endl;
rc |= 1;
continue;
}
- if (!entry->default_value.size() || entry->default_value.compare("none") == 0) {
- fout << "\t/* No default for " << entry->name << " */\n";
+ if (!entry->defaults.preset.size() || entry->defaults.preset.front().compare("none") == 0) {
+ fout << " // No default for " << entry->name << std::endl;
} else {
if (entry->ifdef.size())
fout << "#if " << entry->ifdef << std::endl;
- fout << "\tdefault_line(\"" << entry->name << " " <<
- entry->default_value << "\");\n";
+ for (LineList::const_iterator l = entry->defaults.preset.begin(); l != entry->defaults.preset.end(); ++l) {
+ fout << " default_line(\"" << entry->name << " " << *l << "\");" << std::endl;
+ }
if (entry->ifdef.size())
- fout << "#endif\n";
+ fout << "#endif" << std::endl;
}
}
- fout << "\tcfg_filename = NULL;\n"
- "}\n\n";
+ fout << " cfg_filename = NULL;" << std::endl <<
+ "}" << std::endl << std::endl;
return rc;
}
static void
-gen_default_if_none(Entry * head, std::ostream &fout)
+gen_default_if_none(const EntryList &head, std::ostream &fout)
{
- Entry *entry;
- Line *line;
- fout << "static void\n"
- "defaults_if_none(void)\n"
- "{\n";
+ fout << "static void" << std::endl <<
+ "defaults_if_none(void)" << std::endl <<
+ "{" << std::endl;
- for (entry = head; entry != NULL; entry = entry->next) {
+ for (EntryList::const_iterator entry = head.begin(); entry != head.end(); ++entry) {
assert(entry->name.size());
if (!entry->loc.size())
continue;
- if (entry->default_if_none == NULL)
+ if (entry->defaults.if_none.empty())
continue;
+ if (!entry->defaults.preset.empty()) {
+ std::cerr << "ERROR: " << entry->name << " has preset defaults. DEFAULT_IF_NONE cannot be true." << std::endl;
+ exit(1);
+ }
+
if (entry->ifdef.size())
fout << "#if " << entry->ifdef << std::endl;
- if (entry->default_if_none) {
- fout << "\tif (check_null_" << entry->type << "(" <<
- entry->loc << ")) {\n";
-
- for (line = entry->default_if_none; line; line = line->next)
- fout << "\t\tdefault_line(\"" << entry->name << " " <<
- line->data <<"\");\n";
-
- fout << "\t}\n";
- }
+ fout << " if (check_null_" << entry->type << "(" << entry->loc << ")) {" << std::endl;
+ for (LineList::const_iterator l = entry->defaults.if_none.begin(); l != entry->defaults.if_none.end(); ++l)
+ fout << " default_line(\"" << entry->name << " " << *l <<"\");" << std::endl;
+ fout << " }" << std::endl;
if (entry->ifdef.size())
- fout << "#endif\n";
+ fout << "#endif" << std::endl;
}
- fout << "}\n\n";
+ fout << "}" << std::endl << std::endl;
}
void
-gen_parse_alias(const std::string &name, EntryAlias *alias, Entry *entry, std::ostream &fout)
+Entry::genParseAlias(const std::string &aName, std::ostream &fout) const
{
- fout << "\tif (!strcmp(token, \"" << name << "\")) {\n";
-
- if (entry->type.compare("obsolete") == 0) {
- fout << "\t\tdebugs(0, DBG_CRITICAL, \"ERROR: Directive '" << name << "' is obsolete.\");\n";
- for (Line *line = entry->doc; line != NULL; line = line->next) {
+ fout << " if (!strcmp(token, \"" << aName << "\")) {" << std::endl;
+ fout << " ";
+ if (type.compare("obsolete") == 0) {
+ fout << "debugs(0, DBG_CRITICAL, \"ERROR: Directive '" << aName << "' is obsolete.\");\n";
+ for (LineList::const_iterator l = doc.begin(); l != doc.end(); ++l) {
// offset line to strip initial whitespace tab byte
- fout << "\t\tdebugs(0, opt_parse_cfg_only?0:1, \"" << name << " : " << &line->data[1] << "\");\n";
+ fout << " debugs(0, opt_parse_cfg_only?0:1, \"" << aName << " : " << &(*l)[1] << "\");" << std::endl;
}
- fout << "\t\tparse_obsolete(token);\n";
- } else if (!entry->loc.size() || entry->loc.compare("none") == 0) {
- fout << "\t\tparse_" << entry->type << "();\n";
+ fout << " parse_obsolete(token);";
+ } else if (!loc.size() || loc.compare("none") == 0) {
+ fout << "parse_" << type << "();";
} else {
- fout << "\t\tparse_" << entry->type << "(&" << entry->loc <<
- (entry->array_flag ? "[0]" : "") << ");\n";
+ fout << "parse_" << type << "(&" << loc << (array_flag ? "[0]" : "") << ");";
}
-
- fout << "\t\treturn 1;\n";
- fout << "\t};\n";
+ fout << std::endl;
+ fout << " return 1;" << std::endl;
+ fout << " };" << std::endl;
}
void
-gen_parse_entry(Entry *entry, std::ostream &fout)
+Entry::genParse(std::ostream &fout) const
{
- if (entry->name.compare("comment") == 0)
+ if (name.compare("comment") == 0)
return;
- if (entry->ifdef.size())
- fout << "#if " << entry->ifdef << std::endl;
+ if (ifdef.size())
+ fout << "#if " << ifdef << std::endl;
- std::string &name = entry->name;
+ // Once for the current directive name
+ genParseAlias(name, fout);
- EntryAlias *alias = entry->alias;
-
- bool more;
-
- do {
- gen_parse_alias(name, alias, entry, fout);
- more = false;
-
- if (alias) {
- name = alias->name;
- alias = alias->next;
- more = true;
- }
- } while (more);
+ // All accepted aliases
+ for (EntryAliasList::const_iterator a = alias.begin(); a != alias.end(); ++a) {
+ genParseAlias(*a, fout);
+ }
- if (entry->ifdef.size())
+ if (ifdef.size())
fout << "#endif\n";
}
static void
-gen_parse(Entry * head, std::ostream &fout)
+gen_parse(const EntryList &head, std::ostream &fout)
{
fout <<
"static int\n"
"\tif ((token = strtok(buff, w_space)) == NULL) \n"
"\t\treturn 1;\t/* ignore empty lines */\n";
- for (Entry *entry = head; entry != NULL; entry = entry->next)
- gen_parse_entry (entry, fout);
+ for (EntryList::const_iterator e = head.begin(); e != head.end(); ++e)
+ e->genParse(fout);
fout << "\treturn 0; /* failure */\n"
"}\n\n";
}
static void
-gen_dump(Entry * head, std::ostream &fout)
+gen_dump(const EntryList &head, std::ostream &fout)
{
- Entry *entry;
fout <<
- "static void\n"
- "dump_config(StoreEntry *entry)\n"
- "{\n"
- " debugs(5, 4, HERE);\n";
+ "static void" << std::endl <<
+ "dump_config(StoreEntry *entry)" << std::endl <<
+ "{" << std::endl <<
+ " debugs(5, 4, HERE);" << std::endl;
- for (entry = head; entry != NULL; entry = entry->next) {
+ for (EntryList::const_iterator e = head.begin(); e != head.end(); ++e) {
- if (!entry->loc.size() || entry->loc.compare("none") == 0)
+ if (!e->loc.size() || e->loc.compare("none") == 0)
continue;
- if (entry->name.compare("comment") == 0)
+ if (e->name.compare("comment") == 0)
continue;
- if (entry->ifdef.size())
- fout << "#if " << entry->ifdef << std::endl;
+ if (e->ifdef.size())
+ fout << "#if " << e->ifdef << std::endl;
- fout << "\tdump_" << entry->type << "(entry, \"" << entry->name <<
- "\", " << entry->loc << ");\n";
+ fout << " dump_" << e->type << "(entry, \"" << e->name << "\", " << e->loc << ");" << std::endl;
- if (entry->ifdef.size())
- fout << "#endif\n";
+ if (e->ifdef.size())
+ fout << "#endif" << std::endl;
}
- fout << "}\n\n";
+ fout << "}" << std::endl << std::endl;
}
static void
-gen_free(Entry * head, std::ostream &fout)
+gen_free(const EntryList &head, std::ostream &fout)
{
- Entry *entry;
fout <<
- "static void\n"
- "free_all(void)\n"
- "{\n"
- " debugs(5, 4, HERE);\n";
+ "static void" << std::endl <<
+ "free_all(void)" << std::endl <<
+ "{" << std::endl <<
+ " debugs(5, 4, HERE);" << std::endl;
- for (entry = head; entry != NULL; entry = entry->next) {
- if (!entry->loc.size() || entry->loc.compare("none") == 0)
+ for (EntryList::const_iterator e = head.begin(); e != head.end(); ++e) {
+ if (!e->loc.size() || e->loc.compare("none") == 0)
continue;
- if (entry->name.compare("comment") == 0)
+ if (e->name.compare("comment") == 0)
continue;
- if (entry->ifdef.size())
- fout << "#if " << entry->ifdef << std::endl;
+ if (e->ifdef.size())
+ fout << "#if " << e->ifdef << std::endl;
- fout << "\tfree_" << entry->type << "(&" << entry->loc <<
- (entry->array_flag ? "[0]" : "") << ");\n";
+ fout << " free_" << e->type << "(&" << e->loc << (e->array_flag ? "[0]" : "") << ");" << std::endl;
- if (entry->ifdef.size())
- fout << "#endif\n";
+ if (e->ifdef.size())
+ fout << "#endif" << std::endl;
}
- fout << "}\n\n";
+ fout << "}" << std::endl << std::endl;
}
static bool
-defined(const std::string &name)
+isDefined(const std::string &name)
{
if (!name.size())
return true;
assert(name.size());
for (int i = 0; defines[i].name; i++) {
- if (name.compare(defines[i].name) != 0)
+ if (name.compare(defines[i].name) == 0)
return defines[i].enable;
}
}
static void
-gen_conf(Entry * head, std::ostream &fout, bool verbose_output)
+gen_conf(const EntryList &head, std::ostream &fout, bool verbose_output)
{
- Entry *entry;
- char buf[8192];
- Line *def = NULL;
-
- for (entry = head; entry != NULL; entry = entry->next) {
- Line *line;
+ for (EntryList::const_iterator entry = head.begin(); entry != head.end(); ++entry) {
+ char buf[8192];
+ LineList def;
int enabled = 1;
+ // Display TAG: line
if (!entry->name.compare("comment"))
(void) 0;
else if (!entry->name.compare("obsolete"))
fout << std::endl;
}
- if (!defined(entry->ifdef)) {
+ // Display --enable/--disable disclaimer
+ if (!isDefined(entry->ifdef)) {
if (verbose_output) {
-
- fout << "# Note: This option is only available if "
- "Squid is rebuilt with the\n" <<
- "# " << available_if(entry->ifdef) << "\n#\n";
+ fout << "# Note: This option is only available if Squid is rebuilt with the" << std::endl <<
+ "# " << available_if(entry->ifdef) << std::endl <<
+ "#" << std::endl;
}
enabled = 0;
}
- if (verbose_output) {
- for (line = entry->doc; line != NULL; line = line->next) {
- fout << "#" << line->data << std::endl;
+ // Display DOC_START section
+ if (verbose_output && entry->doc.size()) {
+ for (LineList::const_iterator line = entry->doc.begin(); line != entry->doc.end(); ++line) {
+ fout << "#" << *line << std::endl;
}
}
- if (entry->default_value.size() && entry->default_value.compare("none") != 0) {
- snprintf(buf, sizeof(buf), "%s %s", entry->name.c_str(), entry->default_value.c_str());
- lineAdd(&def, buf);
- }
-
- if (entry->default_if_none) {
- for (line = entry->default_if_none; line != NULL; line = line->next) {
- snprintf(buf, sizeof(buf), "%s %s", entry->name.c_str(), line->data.c_str());
- lineAdd(&def, buf);
+ if (entry->defaults.docs.size()) {
+ // Display the DEFAULT_DOC line(s)
+ def = entry->defaults.docs;
+ } else {
+ if (entry->defaults.preset.size() && entry->defaults.preset.front().compare("none") != 0) {
+ // Display DEFAULT: line(s)
+ for (LineList::const_iterator l = entry->defaults.preset.begin(); l != entry->defaults.preset.end(); ++l) {
+ snprintf(buf, sizeof(buf), "%s %s", entry->name.c_str(), l->c_str());
+ def.push_back(buf);
+ }
+ } else if (entry->defaults.if_none.size()) {
+ // Display DEFAULT_IF_NONE: line(s)
+ for (LineList::const_iterator l = entry->defaults.if_none.begin(); l != entry->defaults.if_none.end(); ++l) {
+ snprintf(buf, sizeof(buf), "%s %s", entry->name.c_str(), l->c_str());
+ def.push_back(buf);
+ }
}
}
- if (!def && entry->doc && !entry->nocomment &&
- entry->name.compare("comment") != 0)
- lineAdd(&def, "none");
+ // Display "none" if no default is set or comments to display
+ if (def.empty() && entry->nocomment.empty() && entry->name.compare("comment") != 0)
+ def.push_back("none");
- if (verbose_output && def && (entry->doc || entry->nocomment)) {
+ if (verbose_output && def.size()) {
fout << "#Default:\n";
- while (def != NULL) {
- line = def;
- def = line->next;
- line->next = NULL; // unlink to simplify delete
- fout << "# " << line->data << std::endl;
- delete line;
+ while (def.size()) {
+ fout << "# " << def.front() << std::endl;
+ def.pop_front();
}
+ if (entry->doc.empty() && entry->nocomment.empty())
+ fout << std::endl;
}
- if (verbose_output && entry->nocomment)
+ if (verbose_output && entry->nocomment.size())
fout << "#" << std::endl;
if (enabled || verbose_output) {
- for (line = entry->nocomment; line != NULL; line = line->next) {
- if (!line->data.size())
- continue;
- if (!enabled && line->data[0] != '#')
- fout << "#" << line->data << std::endl;
- else
- fout << line->data << std::endl;
+ for (LineList::const_iterator line = entry->nocomment.begin(); line != entry->nocomment.end(); ++line) {
+ if (!enabled && line->at(0) != '#')
+ fout << "#";
+ fout << *line << std::endl;
}
}
- if (verbose_output && entry->doc != NULL) {
+ if (verbose_output && entry->doc.size()) {
fout << std::endl;
}
}