From d944f9ab18836d38fcf4e4054e454b0d2c79297b Mon Sep 17 00:00:00 2001 From: daniel-Jones Date: Mon, 15 Oct 2018 14:48:19 +1030 Subject: added cfg.c/h, updated replace.c/h --- cfg.c | 288 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cfg.h | 65 ++++++++++++++ config.h | 17 ++++ main.c | 18 ++++ replace.c | 8 -- replace.h | 7 +- 6 files changed, 390 insertions(+), 13 deletions(-) create mode 100644 cfg.c create mode 100644 cfg.h diff --git a/cfg.c b/cfg.c new file mode 100644 index 0000000..910ce48 --- /dev/null +++ b/cfg.c @@ -0,0 +1,288 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "cfg.h" + +int +cfgsetup(struct cfgfile *cfg, char *filename) +{ + /* + * sets up the cfgfile struct pointed to by cfg, using the cfg + * file location pointed to by filename + */ + cfg->count = 0; + cfg->file = strdup(filename); + if (!cfg->file) + return 0; + FILE *fp; + fp = fopen(cfg->file, "r"); + if (!fp) + return 0; + if (!readfile(cfg, fp)) + { + fclose(fp); + return 0; + } + fclose(fp); + //printlist(cfg->headnode); + return 1; +} + +void +cfgfree(struct cfgfile *cfg) +{ + /* + * frees all memory allocated by cfg + */ + freenodes(cfg->headnode); + free(cfg->file); + free(cfg); +} + +int +cfggetvalue(struct cfgfile *cfg, char *key, char *buffer, size_t buffersize) +{ + /* + * stores the value from the option pointed to by key in buffer with + * a maximum size of buffersize + */ + if (!cfg->headnode) + return 0; + struct cfgnode *tmp = cfg->headnode; + while (tmp) + { + if (strcmp(key, tmp->key) == 0) + { + strncpy(buffer, tmp->value, buffersize); + return 1; + } + tmp = tmp->next; + } + return 0; +} + +void +cfgappendchar(char *dest, char ch) +{ + /* + * appends char ch to dest + * assumes there is enough allocated memory + */ + int len = strlen(dest); + dest[len] = ch; + dest[len+1] = '\0'; +} + +int +readfile(struct cfgfile *cfg, FILE *fp) +{ + /* + * read file pointer to by fp parsing lines + * storing them in the cfgfile structure cfg + */ + cfg->headnode = createnode(); + if (!cfg->headnode) + return 0; + char ch; + size_t bufsize = 30; + size_t linesize = 0; + char *line = NULL; + char *buffer = malloc(bufsize); + if (!buffer) + return 0; + while ((ch = getc(fp)) != EOF) + { + if (!(ch == '\n') && !(ch == '\r')) + { + if (linesize >= bufsize-1) + { + bufsize += 10; + buffer = realloc(buffer, bufsize); + if (!buffer) + return 0; + } + cfgappendchar(buffer, ch); + linesize += sizeof(char); + } + else + { + free(line); + line = strdup(buffer); + if (!line) + { + free(buffer); + return 0; + } + if (!parseline(line, cfg)) + { + free(line); + free(buffer); + return 0; + } + buffer[0] = '\0'; + /* I could free buffer here, though I don't + * see a point, we already have the memory + * allocated, may as well keep it */ + linesize = 0; + } + } + free(line); + free(buffer); + return 1; +} + +int +parseline(char *line, struct cfgfile *cfg) +{ + /* parse line pointed to by line string + * results in a cfgnode node appended to head */ + + /* determine if the line is a comment (#) + * also strip whitespaces from the beginning */ + char ch = line[0]; + while (ch == ' ' || ch == '\t') + { + memmove(line, line+1, strlen(line)); + ch = line[0]; + } + if (ch == '#') + return 1; + else + { + // TODO: strip whitespaces from the key and value + // while key[strlen(key)-1 == ' '] + struct cfgnode *tmp; + if (cfg->count == 0) + tmp = cfg->headnode; + else + { + tmp = createnode(); + if (!tmp) + return 0; + if (!addnode(cfg->headnode, tmp)) + return 0; + } + // malloc memory for key and value + int c = 0; + int doingkey = 1; + size_t keybufsize = 1; + size_t keysize = 255; + size_t valbufsize = 255; + size_t valsize = 0; + tmp->key = malloc(keybufsize); + tmp->value = malloc(valbufsize); + if (!tmp->key) + return 0; + while ((ch = line[c]) != '\0') + { + if (doingkey) + { + if (ch == '=') + doingkey = 0; + else + { + if (keysize >= keybufsize-1) + { + keybufsize += 10; + tmp->key = realloc(tmp->key, keybufsize); + if (!tmp->key) + return 0; + } + cfgappendchar(tmp->key, ch); + valsize += sizeof(char); + } + } + else + { + if (valsize >= valbufsize-1) + { + valbufsize += 10; + tmp->value = realloc(tmp->value, valbufsize); + if (!tmp->value) + return 0; + } + cfgappendchar(tmp->value, ch); + valsize += sizeof(char); + } + c++; + } + cfg->count++; + } + return 1; +} + +struct cfgnode +*createnode(void) +{ + /* + * create a cfgnode and return a pointer to it + */ + struct cfgnode *tmp = malloc(sizeof(struct cfgnode)); + if (!tmp) + return NULL; + tmp->next = NULL; + tmp->key = NULL; + tmp->value = NULL; + return tmp; +} + +int +addnode(struct cfgnode *head, struct cfgnode *node) +{ + /* + * add a cfgnode to the end head + */ + if (!head || !node) + return 0; + struct cfgnode *tmp = head; + while (tmp->next) + tmp = tmp->next; + tmp->next = node; + return 1; +} + +void +freenodes(struct cfgnode *head) +{ + /* + * free all cfgnode in the linked list + */ + if (!head) + return; + struct cfgnode *tmp; + while (head) + { + tmp = head; + head = head->next; + free(tmp->key); + free(tmp->value); + free(tmp); + } +} + +void +printlist(struct cfgnode *head) +{ + struct cfgnode *tmp = head; + while (tmp) + { + printf("key: %s\nvalue: %s\n", tmp->key, tmp->value); + tmp = tmp->next; + } +} diff --git a/cfg.h b/cfg.h new file mode 100644 index 0000000..d7ddb93 --- /dev/null +++ b/cfg.h @@ -0,0 +1,65 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CFG_H +#define CFG_H + +struct +cfgfile +{ + char *file; + struct cfgnode *headnode; + int count; +}; + +struct +cfgnode +{ + char *key; + char *value; + struct cfgnode *next; +}; + +int +cfgsetup(struct cfgfile *cfg, char *filename); + +void +cfgfree(struct cfgfile *cfg); + +int +cfggetvalue(struct cfgfile *cfg, char *key, char *buffer, size_t buffersize); + +void +cfgappendchar(char *dest, char ch); + +int +readfile(struct cfgfile *cfg, FILE *fp); + +int +parseline(char *line, struct cfgfile *cfg); + +struct cfgnode +*createnode(void); + +int +addnode(struct cfgnode *head, struct cfgnode *node); + +void +freenodes(struct cfgnode *head); + +void +printlist(struct cfgnode *head); + +#endif diff --git a/config.h b/config.h index fa13e11..19555bb 100644 --- a/config.h +++ b/config.h @@ -1,6 +1,23 @@ +/* + * This file is part of websitegen, a website generator for https://danieljon.es + * Copyright (C) 2018 Daniel Jones daniel@danieljon.es + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ /* blog */ const char *blogindir = "content/blog/"; const char *blogoutdir = "output/blog/"; const int postsperpage = 10; const char *blogtitle = "daniel's blog"; +const char *header = "

Blog

Rambles about programming, technology and life.

"; diff --git a/main.c b/main.c index 2f4ba5c..f51541f 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,24 @@ +/* + * This file is part of websitegen, a website generator for https://danieljon.es + * Copyright (C) 2018 Daniel Jones daniel@danieljon.es + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include "replace.h" #include "config.h" +#include "cfg.h" int main(void) diff --git a/replace.c b/replace.c index f9d66fe..1860d9e 100644 --- a/replace.c +++ b/replace.c @@ -37,14 +37,6 @@ getfilelength(FILE *fp) return retval; } -void -appendchar(char *dest, char ch) -{ - int len = strlen(dest); - dest[len] = ch; - dest[len+1] = '\0'; -} - int replaceinfile(char *originalfile, char *destinationfile, char *placeholder, char *replacement) { diff --git a/replace.h b/replace.h index 8b0089c..1b1d4a7 100644 --- a/replace.h +++ b/replace.h @@ -3,12 +3,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program 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 General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -19,9 +19,6 @@ size_t getfilelength(FILE *fp); -void -appendchar(char *dest, char ch); - int replaceinfile(char *originalfile, char *destinationfile, char *placeholder, char *replacement); -- cgit v1.2.3