From 6b4c7eecb5910b35ac61452cd5515ff1ee03d1de Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 7 Apr 2013 15:33:37 +0200 Subject: [PATCH] Parse a config file. Not used for anything yet. --- cubemap.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 4 deletions(-) diff --git a/cubemap.cpp b/cubemap.cpp index ed615a8..3f136aa 100644 --- a/cubemap.cpp +++ b/cubemap.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -171,16 +172,102 @@ CubemapStateProto read_tempfile(int state_fd) return state; } +// Split a line on whitespace, e.g. "foo bar baz" -> {"foo", "bar", "baz"}. +vector split_tokens(const string &line) +{ + vector ret; + string current_token; + + for (size_t i = 0; i < line.size(); ++i) { + if (isspace(line[i])) { + if (!current_token.empty()) { + ret.push_back(current_token); + } + current_token.clear(); + } else { + current_token.push_back(line[i]); + } + } + if (!current_token.empty()) { + ret.push_back(current_token); + } + return ret; +} + +struct ConfigLine { + string keyword; + vector arguments; + map parameters; +}; + +// Parse the configuration file. +vector parse_config(const string &filename) +{ + vector ret; + + FILE *fp = fopen(filename.c_str(), "r"); + if (fp == NULL) { + perror(filename.c_str()); + exit(1); + } + + char buf[4096]; + while (!feof(fp)) { + if (fgets(buf, sizeof(buf), fp) == NULL) { + break; + } + + // Chop off the string at the first #, \r or \n. + buf[strcspn(buf, "#\r\n")] = 0; + + // Remove all whitespace from the end of the string. + size_t len = strlen(buf); + while (len > 0 && isspace(buf[len - 1])) { + buf[--len] = 0; + } + + // If the line is now all blank, ignore it. + if (len == 0) { + continue; + } + + vector tokens = split_tokens(buf); + assert(!tokens.empty()); + + ConfigLine line; + line.keyword = tokens[0]; + + for (size_t i = 1; i < tokens.size(); ++i) { + // foo=bar is a parameter; anything else is an argument. + size_t equals_pos = tokens[i].find_first_of('='); + if (equals_pos == string::npos) { + line.arguments.push_back(tokens[i]); + } else { + string key = tokens[i].substr(0, equals_pos); + string value = tokens[i].substr(equals_pos + 1, string::npos); + line.parameters.insert(make_pair(key, value)); + } + } + + ret.push_back(line); + } + + fclose(fp); +} + int main(int argc, char **argv) { fprintf(stderr, "\nCubemap starting.\n"); - + + string config_filename = (argc == 1) ? "cubemap.config" : argv[1]; + vector config = parse_config(config_filename); + servers = new Server[NUM_SERVERS]; int server_sock; - if (argc == 3 && strcmp(argv[1], "-state") == 0) { + if (argc == 4 && strcmp(argv[2], "-state") == 0) { fprintf(stderr, "Deserializing state from previous process... "); - int state_fd = atoi(argv[2]); + int state_fd = atoi(argv[3]); CubemapStateProto loaded_state = read_tempfile(state_fd); // Deserialize the streams. @@ -250,7 +337,7 @@ int main(int argc, char **argv) sprintf(buf, "%d", state_fd); for ( ;; ) { - execlp(argv[0], argv[0], "-state", buf, NULL); + execlp(argv[0], argv[0], config_filename.c_str(), "-state", buf, NULL); perror("execlp"); fprintf(stderr, "PANIC: re-exec of %s failed. Waiting 0.2 seconds and trying again...\n", argv[0]); usleep(200000); -- 2.39.2