/* * Copyright (C) 2022 luca0N! * * This file is part of Static Website Generator (swg). * * Static Website Generator (swg) is free software: you can redistribute it * and/or modify it under the terms of the version 3 of the GNU Lesser General * Public License as published by the Free Software Foundation. * * Static Website Generator (swg) is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Static Website Generator (swg). If not, see * . * * Contact luca0N! by e-mail: . */ #include "ConfigUtils.hxx" #include #include #include #include "Common.hxx" void parse_config(SwgContext *ctx, std::string const &path) { std::string ctxCfgPath = path; ctxCfgPath += "/swg.cfg"; FILE *ctxCfgFile = fopen(ctxCfgPath.c_str(), "r"); if (ctxCfgFile == NULL) { std::cerr << "error: cannot open swg.cfg file, are you sure " << path << " is a valid SWG directory?" << std::endl; perror(ctxCfgPath.c_str()); exit(RETURN_FAILED_INVALID_DIRECTORY); } int buflen = 16; char cbuf[buflen]; // Yes, this looks ugly, but it works for now. Will probably optimize // this in the future :) // // TODO: Optimize config file interpretation std::list lines = { "" }; while (fgets(cbuf, buflen, ctxCfgFile) != NULL) { int eol = -1; for (int c = 0; c < buflen; c++) { if (cbuf[c] == '\0') { break; } else if (cbuf[c] == '\n') { eol = c; break; } } if (eol > -1) { cbuf[eol] = '\0'; *(--lines.end()) += cbuf; lines.insert(lines.end(), ""); } else *(--lines.end()) += cbuf; } fclose(ctxCfgFile); std::cout << "Done loading configuration file in memory" << std::endl; // Parse configuration file enum ConfigNamespace { General, Blogs }; ConfigNamespace ns; int blogCount = 0; Blog *currentBlog = NULL; // (Blog*) malloc(sizeof(Blog)); // currentBlog->name = "asd"; for (std::string line : lines) { // Skip comment lines if (line.c_str()[0] == '#') continue; if (line.c_str()[0] == '[') { if (line == "[General]") { ns = General; continue; } else if (line == "[Blogs]") { ns = Blogs; continue; } else { std::cerr << "error: unknown namespace in config file: " << line << std::endl; exit(RETURN_FAILED_CONFIG_INVALID_SYNTAX); } } // Skip empty lines if (line == "") continue; int end = line.find("="); std::string k = line.substr(0, end), v = line.substr(end + 2, (line.length() - 1) - (end + 2)); switch (ns) { case General: if (k == "WebsiteName") ctx->websiteName = v; else if (k == "WebsitePublisher") ctx->websitePublisher = v; else if (k == "WebsiteCopyrightHolder") ctx->websiteCopyrightHolder = v; else if (k == "WebsiteCopyrightYears") ctx->websiteCopyrightYears = v; else if (k == "websiteContentLicense") ctx->websiteContentLicense = v; else std::cerr << "warning: unknown key in namespace \"General\": " << k << std::endl; continue; case Blogs: // FIXME: This code only accepts up to 9 blogs. if (line.substr(0, 4) == "Blog") { // Check No. int blogNo = atoi(line.substr(4, 1).c_str()); if (blogNo != blogCount && blogNo != blogCount +1){ std::cerr << "error: blog declaration must be incremental (received " << blogNo << " instead of " << blogCount << " or " << blogCount + 1 << ")" << std::endl; exit(RETURN_FAILED_CONFIG_INVALID_SYNTAX); } else if (blogNo == blogCount + 1) { blogCount++; if (currentBlog != NULL) ctx->blogs.push_back(currentBlog); currentBlog = (Blog*) malloc(sizeof(Blog)); // Clear allocated memory memset(currentBlog, 0, sizeof(Blog)); } assert(currentBlog != NULL); //std::cout << "Attempting to set K/V" << std::endl; if (k.substr(5) == "Path") { //std::cout << "Setting path (" << v << ") for " << blogCount << std::endl; strncpy(currentBlog->path, v.c_str(), sizeof(currentBlog->path)); } else if (k.substr(5) == "Name") { //std::cout << "Setting name (" << v << ") for " << blogCount << std::endl; strncpy(currentBlog->name, v.c_str(), sizeof(currentBlog->name)); } else if (k.substr(5) == "Dir") { strncpy(currentBlog->dir, v.c_str(), sizeof(currentBlog->dir)); } else { std::cerr << "warning: unknown key in namespace \"Blogs\": " << k << "\n"; } } continue; } } if (currentBlog != NULL) ctx->blogs.push_back(currentBlog); /*std::cout << "Loaded " << blogCount << " blogs into memory" << std::endl; for (Blog *b : ctx->blogs) { std::cout << "\t" << b->name << ": " << b->path << std::endl; }*/ }