| @@ -1,4 +1,4 @@ | |||
| <article> | |||
| <header> | |||
| <h1>{title}</h1> | |||
| <h1>{{title}}</h1> | |||
| </article> | |||
| @@ -3,13 +3,13 @@ | |||
| <head> | |||
| <meta charset="utf-8"> | |||
| <link rel="stylesheet" href="/_style.css"> | |||
| <title>{title}</title> | |||
| <title>{{title}}</title> | |||
| </head> | |||
| <body> | |||
| {menu} | |||
| {{menu}} | |||
| <div id="articles"> | |||
| {articles} | |||
| {{articles}} | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @@ -1,8 +1,8 @@ | |||
| <div class="page"> | |||
| <span class="name"> | |||
| {name} | |||
| {{name}} | |||
| </span> | |||
| <div class="sub"> | |||
| {sub} | |||
| {{sub}} | |||
| </div> | |||
| </div> | |||
| @@ -1,5 +1,5 @@ | |||
| <header class="menu"> | |||
| <nav class="menu-nav"> | |||
| {pages} | |||
| {{pages}} | |||
| </nav> | |||
| </header> | |||
| @@ -17,18 +17,57 @@ | |||
| #include <stdio.h> | |||
| cms_err* cms_build_write_files(cms_page* root, char* path) | |||
| static char* make_post(cms_page* parent, cms_post post, char* rootpath) | |||
| { | |||
| char* fstr; | |||
| char* fname; | |||
| cms_template_args* args; | |||
| cms_err* err; | |||
| char* str; | |||
| //Template index.html | |||
| fname = cms_util_path_join(rootpath, CMS_FILE_THEME "/html/index.html"); | |||
| if (fname == NULL) return NULL; | |||
| fstr = cms_util_file_read(fname); | |||
| if (fstr == NULL) return NULL; | |||
| args = cms_template_args_create(); | |||
| err = cms_template_args_append(args, "articles", post.html); | |||
| if (err) return NULL; | |||
| str = cms_templateify(fstr, args); | |||
| if (str == NULL) return NULL; | |||
| free(fstr); | |||
| free(fname); | |||
| free(args); | |||
| free(err); | |||
| return str; | |||
| } | |||
| cms_err* cms_build_write_files(cms_page* root, char* path, char* rootpath) | |||
| { | |||
| printf( | |||
| "page: '%s', n posts: %i, n subs: %i\n", | |||
| root->title, | |||
| (int)root->numposts, | |||
| (int)root->numsubs | |||
| ); | |||
| char* dirpath = cms_util_path_join(path, root->slug); | |||
| if (dirpath == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| if (mkdir(dirpath, 077) == -1 && errno != EEXIST) | |||
| return cms_err_from_std_err(errno); | |||
| if (mkdir(dirpath, 0777) == -1 && errno != EEXIST) | |||
| return cms_err_from_std_err(errno, dirpath); | |||
| //Go through each post in the page, writing it to disk | |||
| size_t i; | |||
| for (i = 0; i < root->numposts; ++i) | |||
| for (i = 0; i < (root->numposts); ++i) | |||
| { | |||
| cms_post post = root->posts[i]; | |||
| @@ -37,17 +76,25 @@ cms_err* cms_build_write_files(cms_page* root, char* path) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| if (mkdir(postdirpath, 0777) == -1 && errno != EEXIST) | |||
| return cms_err_from_std_err(errno); | |||
| return cms_err_from_std_err(errno, postdirpath); | |||
| char* filepath = cms_util_path_join(postdirpath, CMS_FILE_INDEX); | |||
| if (postdirpath == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| int file = open(filepath, O_WRONLY | O_CREAT, 0777); | |||
| int file = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0777); | |||
| if (file == -1) | |||
| return cms_err_from_std_err(errno); | |||
| return cms_err_from_std_err(errno, NULL); | |||
| write(file, post.html, strlen(post.html)); | |||
| //Create the HTML for the post | |||
| char* html = make_post(root, post, rootpath); | |||
| if (html == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| //Write post's HTML file | |||
| ssize_t nbytes = write(file, html, strlen(html)); | |||
| if (nbytes == -1) | |||
| return cms_err_from_std_err(errno, NULL); | |||
| close(file); | |||
| free(filepath); | |||
| @@ -63,7 +110,12 @@ cms_err* cms_build_write_files(cms_page* root, char* path) | |||
| if (subdirpath == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| cms_build_write_files(&sub, subdirpath); | |||
| if (mkdir(subdirpath, 0777) == -1 && errno != EEXIST) | |||
| return cms_err_from_std_err(errno, subdirpath); | |||
| cms_err* err = cms_build_write_files(&sub, subdirpath, rootpath); | |||
| if (err) | |||
| return err; | |||
| free(subdirpath); | |||
| } | |||
| @@ -78,7 +130,7 @@ cms_err* cms_build_make_tree(cms_page* root, char* path, char* dirname) | |||
| struct dirent** namelist; | |||
| int n = scandir(path, &namelist, 0, alphasort); | |||
| if (n == -1) | |||
| return cms_err_from_std_err(errno); | |||
| return cms_err_from_std_err(errno, NULL); | |||
| struct dirent* ep; | |||
| @@ -4,7 +4,7 @@ | |||
| #include "cms_err.h" | |||
| #include "cms_page.h" | |||
| cms_err* cms_build_write_files(cms_page* root, char* path); | |||
| cms_err* cms_build_write_files(cms_page* root, char* path, char* rootpath); | |||
| cms_err* cms_build_make_tree(cms_page* root, char* path, char* dirname); | |||
| @@ -104,27 +104,27 @@ void cms_err_panic(cms_err* err) | |||
| exit(1); | |||
| } | |||
| cms_err* _cms_err_from_std_err(int err, const char* file, int line) | |||
| cms_err* _cms_err_from_std_err(int err, char* msg, const char* file, int line) | |||
| { | |||
| switch (err) | |||
| { | |||
| case EACCES: | |||
| return _cms_err_create(CMS_ERR_PERM, NULL, file, line); | |||
| return _cms_err_create(CMS_ERR_PERM, msg, file, line); | |||
| case EEXIST: | |||
| return _cms_err_create(CMS_ERR_FILEEXISTS, NULL, file, line); | |||
| return _cms_err_create(CMS_ERR_FILEEXISTS, msg, file, line); | |||
| case EFAULT: | |||
| return _cms_err_create(CMS_ERR_PERM, NULL, file, line); | |||
| return _cms_err_create(CMS_ERR_PERM, msg, file, line); | |||
| case EISDIR: | |||
| return _cms_err_create(CMS_ERR_NOTFILE, NULL, file, line); | |||
| return _cms_err_create(CMS_ERR_NOTFILE, msg, file, line); | |||
| case ENOENT: | |||
| return _cms_err_create(CMS_ERR_NOENT, NULL, file, line); | |||
| return _cms_err_create(CMS_ERR_NOENT, msg, file, line); | |||
| case ENOMEM: | |||
| return _cms_err_create(CMS_ERR_ALLOC, NULL, file, line); | |||
| return _cms_err_create(CMS_ERR_ALLOC, msg, file, line); | |||
| case ENOTDIR: | |||
| return _cms_err_create(CMS_ERR_NOTDIR, NULL, file, line); | |||
| return _cms_err_create(CMS_ERR_NOTDIR, msg, file, line); | |||
| case EROFS: | |||
| return _cms_err_create(CMS_ERR_PERM, NULL, file, line); | |||
| return _cms_err_create(CMS_ERR_PERM, msg, file, line); | |||
| default: | |||
| return _cms_err_create(CMS_ERR_UNKNOWN, NULL, file, line); | |||
| return _cms_err_create(CMS_ERR_UNKNOWN, msg, file, line); | |||
| } | |||
| } | |||
| @@ -34,8 +34,8 @@ void cms_err_free(cms_err* err); | |||
| void cms_err_panic(cms_err* err); | |||
| cms_err* _cms_err_from_std_err(int err, const char* file, int line); | |||
| #define cms_err_from_std_err(err) _cms_err_from_std_err(err, __FILE__, __LINE__) | |||
| cms_err* _cms_err_from_std_err(int err, char* msg, const char* file, int line); | |||
| #define cms_err_from_std_err(err, msg) _cms_err_from_std_err(err, msg, __FILE__, __LINE__) | |||
| #endif | |||
| @@ -8,12 +8,15 @@ | |||
| #define CMS_FILE_INITED ".cmsinited" | |||
| //The name of the dir which specifies the title and | |||
| //other metadata of a page | |||
| //other metadata of a page. | |||
| #define CMS_FILE_PAGE "page" | |||
| //Directory containing the user's resources. | |||
| #define CMS_FILE_ROOT "pages" | |||
| //Directory containing the user's theme. | |||
| #define CMS_FILE_THEME "theme" | |||
| //Directory to write the output to. | |||
| #define CMS_FILE_OUT "public" | |||
| @@ -3,6 +3,8 @@ | |||
| #include "cms_template.h" | |||
| #include <stdio.h> | |||
| cms_template_args* cms_template_args_create() | |||
| { | |||
| cms_template_args* args = malloc(sizeof(cms_template_args)); | |||
| @@ -22,7 +24,11 @@ cms_err* cms_template_args_append(cms_template_args* args, char* key, char* val) | |||
| if (args->argnum > args->allocd) | |||
| { | |||
| args->allocd *= 2; | |||
| if (!args->allocd) | |||
| args->allocd = 1; | |||
| else | |||
| args->allocd *= 2; | |||
| args->arguments = realloc( | |||
| args->arguments, | |||
| sizeof(cms_template_arg) * args->allocd | |||
| @@ -31,7 +37,14 @@ cms_err* cms_template_args_append(cms_template_args* args, char* key, char* val) | |||
| return cms_err_create(CMS_ERR_ALLOC, 0); | |||
| } | |||
| cms_template_arg arg = {key, val}; | |||
| //Wrap key in {{ and }} | |||
| size_t len = strlen(key); | |||
| char* fullkey = malloc(len + 5); | |||
| memcpy(fullkey, "{{", 2); | |||
| memcpy(fullkey + 2, key, len); | |||
| memcpy(fullkey + len + 2, "}}\0", 3); | |||
| cms_template_arg arg = {fullkey, val}; | |||
| args->arguments[args->argnum - 1] = arg; | |||
| return cms_err_create(CMS_ERR_NONE, NULL); | |||
| @@ -42,21 +55,21 @@ static char* str_insert( | |||
| char* str2, | |||
| size_t start, | |||
| size_t end, | |||
| size_t len) | |||
| size_t str1len) | |||
| { | |||
| size_t len2 = strlen(str2); | |||
| size_t str2len = strlen(str2); | |||
| str1 = realloc(str1, len + len2 - (end - start)); | |||
| str1 = realloc(str1, str1len + str2len - (end - start)); | |||
| if (str1 == NULL) | |||
| return NULL; | |||
| memmove(str1 + end, str1 + start, len - start); | |||
| memcpy(str1 + start, str2, len2); | |||
| memcpy(str1 + start + str2len, str1 + end, str1len - end); | |||
| memcpy(str1 + start, str2, str2len); | |||
| return str1; | |||
| } | |||
| static char* templatify_arg(char* str, cms_template_arg arg, size_t len) | |||
| static char* templateify_arg(char* str, cms_template_arg arg, size_t len) | |||
| { | |||
| #define OFFSET i - match_start | |||
| @@ -95,17 +108,24 @@ static char* templatify_arg(char* str, cms_template_arg arg, size_t len) | |||
| return str; | |||
| } | |||
| char* cms_templateify(char* str, cms_template_args* args) | |||
| char* cms_templateify(char* fstr, cms_template_args* args) | |||
| { | |||
| size_t len = strlen(str); | |||
| size_t len = strlen(fstr); | |||
| char* str = malloc(len); | |||
| if (str == NULL) | |||
| return NULL; | |||
| memcpy(str, fstr, len); | |||
| size_t i; | |||
| for (i = 0; i < args->argnum; ++i) | |||
| { | |||
| str = templatify_arg(str, args->arguments[i], len); | |||
| str = templateify_arg(str, args->arguments[i], len); | |||
| if (str == NULL) | |||
| return NULL; | |||
| } | |||
| len = strlen(str); | |||
| } | |||
| return str; | |||
| } | |||
| @@ -35,7 +35,7 @@ cms_err* cms_util_file_create(char* fname) | |||
| close(f); | |||
| if (f == -1) | |||
| return cms_err_from_std_err(errno); | |||
| return cms_err_from_std_err(errno, NULL); | |||
| else | |||
| return cms_err_create(CMS_ERR_NONE, NULL); | |||
| } | |||
| @@ -44,11 +44,11 @@ cms_err* cms_util_file_copy(char* fname1, char* fname2) | |||
| { | |||
| int f1 = open(fname1, O_RDONLY); | |||
| if (f1 == -1) | |||
| return cms_err_from_std_err(errno); | |||
| return cms_err_from_std_err(errno, NULL); | |||
| int f2 = open(fname2, O_WRONLY | O_CREAT, 0777); | |||
| if (f1 == -1) | |||
| return cms_err_from_std_err(errno); | |||
| return cms_err_from_std_err(errno, NULL); | |||
| struct stat* st = malloc(sizeof(struct stat)); | |||
| if (st == NULL) | |||
| @@ -100,11 +100,11 @@ char* cms_util_file_read(char* fname) | |||
| cms_err* cms_util_dir_copy_recursive(char* dir1, char* dir2) | |||
| { | |||
| if (mkdir(dir2, 0777) == -1 && errno != EEXIST) | |||
| return cms_err_from_std_err(errno); | |||
| return cms_err_from_std_err(errno, NULL); | |||
| DIR* dp = opendir(dir1); | |||
| if (dp == NULL) | |||
| return cms_err_from_std_err(errno); | |||
| return cms_err_from_std_err(errno, NULL); | |||
| struct dirent* ep; | |||
| @@ -121,7 +121,7 @@ cms_err* cms_util_dir_copy_recursive(char* dir1, char* dir2) | |||
| char* path2 = cms_util_path_join(dir2, ep->d_name); | |||
| if (stat(path1, st) == -1) | |||
| return cms_err_from_std_err(errno); | |||
| return cms_err_from_std_err(errno, NULL); | |||
| if (S_ISDIR(st->st_mode)) | |||
| { | |||
| @@ -8,29 +8,6 @@ | |||
| #include "cms_page.h" | |||
| #include "cms_build.h" | |||
| //Temporary, for testing purposes | |||
| static void print_page_tree(cms_page* page) | |||
| { | |||
| if (page->title) | |||
| printf("Page: %s\n", page->title); | |||
| //Loop over posts | |||
| size_t i; | |||
| for (i = 0; i < page->numposts; ++i) | |||
| { | |||
| printf("printing post\n"); | |||
| printf("\tPost: %s\n", (page->posts[i]).title); | |||
| } | |||
| //Loop over subs | |||
| for (i = 0; i < page->numsubs; ++i) | |||
| { | |||
| print_page_tree(&page->subs[i]); | |||
| } | |||
| printf("---------\n"); | |||
| } | |||
| int main(int argc, char** argv) | |||
| { | |||
| if (argc < 2) | |||
| @@ -94,6 +71,8 @@ int main(int argc, char** argv) | |||
| cms_page* root = cms_page_create(); | |||
| if (root == NULL) | |||
| cms_err_panic(cms_err_create(CMS_ERR_ALLOC, NULL)); | |||
| root->slug = ""; | |||
| root->title = ""; | |||
| char* path = cms_util_path_join(dirname, CMS_FILE_ROOT); | |||
| if (path == NULL) | |||
| @@ -110,9 +89,9 @@ int main(int argc, char** argv) | |||
| if (outpath == NULL) | |||
| cms_err_panic(cms_err_create(CMS_ERR_ALLOC, NULL)); | |||
| cms_build_write_files(root, outpath); | |||
| print_page_tree(root); | |||
| err = cms_build_write_files(root, outpath, dirname); | |||
| if (err) | |||
| cms_err_panic(err); | |||
| } | |||
| //Nothing, print usage | |||