usage
}
-void usage (const char *programme)
+
+static void
usage (void)
you must free() the memory!
diff --git a/doc/Widget.html b/doc/Widget.html
index 4dc6f34..662c2b9 100644
--- a/doc/Widget.html
+++ b/doc/Widget.html
@@ -53,77 +53,77 @@
int |
WidgetContent |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetDate |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetFilealt |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetFiledesc |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetFilehref |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetFileicon |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetFilename |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetFiles |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetFilesize |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetNews |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetNewsname |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetNow |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetPwd |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetRoot |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
int |
WidgetTitle |
- const struct Files *f, FILE *fp |
+ struct Files *const f, FILE *const fp |
@@ -132,7 +132,7 @@
WidgetContent
-
int WidgetContent (const struct Files *f, FILE *fp)
+
int WidgetContent (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -141,7 +141,7 @@
WidgetDate
-
int WidgetDate (const struct Files *f, FILE *fp)
+
int WidgetDate (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -150,7 +150,7 @@
WidgetFilealt
-
int WidgetFilealt (const struct Files *f, FILE *fp)
+
int WidgetFilealt (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -159,7 +159,7 @@
WidgetFiledesc
-
int WidgetFiledesc (const struct Files *f, FILE *fp)
+
int WidgetFiledesc (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -168,7 +168,7 @@
WidgetFilehref
-
int WidgetFilehref (const struct Files *f, FILE *fp)
+
int WidgetFilehref (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -177,7 +177,7 @@
WidgetFileicon
-
int WidgetFileicon (const struct Files *f, FILE *fp)
+
int WidgetFileicon (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -186,7 +186,7 @@
WidgetFilename
-
int WidgetFilename (const struct Files *f, FILE *fp)
+
int WidgetFilename (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -195,7 +195,7 @@
WidgetFiles
-
int WidgetFiles (const struct Files *f, FILE *fp)
+
int WidgetFiles (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -204,7 +204,7 @@
WidgetFilesize
-
int WidgetFilesize (const struct Files *f, FILE *fp)
+
int WidgetFilesize (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -213,7 +213,7 @@
WidgetNews
-
int WidgetNews (const struct Files *f, FILE *fp)
+
int WidgetNews (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -222,7 +222,7 @@
WidgetNewsname
-
int WidgetNewsname (const struct Files *f, FILE *fp)
+
int WidgetNewsname (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -231,7 +231,7 @@
WidgetNow
-
int WidgetNow (const struct Files *f, FILE *fp)
+
int WidgetNow (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -240,7 +240,7 @@
WidgetPwd
-
int WidgetPwd (const struct Files *f, FILE *fp)
+
int WidgetPwd (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -249,7 +249,7 @@
WidgetRoot
-
int WidgetRoot (const struct Files *f, FILE *fp)
+
int WidgetRoot (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
@@ -258,7 +258,7 @@
WidgetTitle
-
int WidgetTitle (const struct Files *f, FILE *fp)
+
int WidgetTitle (struct Files *const f, FILE *const fp)
- implements
- ParserWidget
diff --git a/src/Files.c b/src/Files.c
index 0eb8548..d20cf32 100644
--- a/src/Files.c
+++ b/src/Files.c
@@ -7,8 +7,8 @@
@title Files
@author Neil
- @std C89/90
- @version 1.1; 2017-03 fixed pedantic warnings; took out arg
+ @std POSIX
+ @version 1.1; 2017-03 fixed pedantic warnings; command-line improvements
@since 0.6; 2008-03-24 */
#include /* malloc free */
@@ -19,9 +19,9 @@
#include "Files.h"
/* constants */
-const char *dirCurrent = "."; /* used in multiple files */
-const char *dirParent = "..";
-static const size_t maxFilename = 128;
+const char *dir_current = "."; /* used in multiple files */
+const char *dir_parent = "..";
+static const size_t max_filename = 128;
/* public */
struct Files {
@@ -45,19 +45,23 @@ static struct File *File(const char *name, const int size, const int isDir);
static void File_(struct File *file);
static int FileInsert(struct File *file, struct File **startAddr);
-/** parent->this must be the 'file' (directory) that you want to create */
-struct Files *Files(const struct Files *parent, const FilesFilter filter) {
- char *dirName;
+/** Directory information.
+ @param parent: {parent->this} must be the 'file' (directory) that you want to
+ create.
+ @param filter: This returns true on the files that you want included. */
+struct Files *Files(struct Files *const parent, const FilesFilter filter) {
+ const char *dirName;
struct dirent *de;
struct stat st;
struct File *file;
struct Files *files;
DIR *dir;
- if(parent && !parent->this) { fprintf(stderr, "Files: tried creating a directory without selecting a file (parent->this.)\n"); return 0; }
+ if(parent && !parent->this) { fprintf(stderr, "Files: tried creating a "
+ "directory without selecting a file (parent->this.)\n"); return 0; }
files = malloc(sizeof(struct Files));
if(!files) { perror("files"); Files_(files); return 0; }
/* does not check for recusive dirs - assumes that it is a tree */
- files->parent = (struct Files *)parent;
+ files->parent = parent;
files->favourite = 0;
files->file = parent ? parent->this : 0;
files->firstFile = 0;
@@ -69,8 +73,8 @@ struct Files *Files(const struct Files *parent, const FilesFilter filter) {
while((dirName = FilesEnumPath(files))) fprintf(stderr, "%s/", dirName);
fprintf(stderr, ">.\n");
/* read the current dir */
- dir = opendir(dirCurrent);
- if(!dir) { perror(dirParent); Files_(files); return 0; }
+ dir = opendir(dir_current);
+ if(!dir) { perror(dir_parent); Files_(files); return 0; }
while((de = readdir(dir))) {
int error = 0;
/* ignore certain files, incomplete 'files'! -> Recusor.c */
@@ -89,9 +93,10 @@ struct Files *Files(const struct Files *parent, const FilesFilter filter) {
/* error */
if(error) fprintf(stderr, "Files: <%s> missed being included on the list.\n", de->d_name);
}
- if(closedir(dir)) { perror(dirCurrent); }
+ if(closedir(dir)) { perror(dir_current); }
return files;
}
+
/** Destructor. */
void Files_(struct Files *files) {
if(!files) return;
@@ -99,9 +104,7 @@ void Files_(struct Files *files) {
File_(files->firstFile);
free(files);
}
-/* this is how we used to access files before 'invisiblity'
- if((f->this)) return f->this->next ? -1 : f->firstFile ? -1 : 0;
- if((f->this)) return f->this->next ? -1 : 0; */
+
/** This is how we access the files sequentially. */
int FilesAdvance(struct Files *f) {
static enum { files, dirs } type = dirs;
@@ -120,19 +123,23 @@ int FilesAdvance(struct Files *f) {
}
return 0;
}
+
/** Doesn't have a parent? */
int FilesIsRoot(const struct Files *f) {
if(!f) return 0;
return (f->parent) ? 0 : -1;
}
+
/** Resets the list of favourites. */
void FilesSetPath(struct Files *f) {
if(!f) return;
for( ; f->parent; f = f->parent) f->parent->favourite = f;
}
-/** After FilesSetFarourite, this enumerates them. */
-char *FilesEnumPath(struct Files *f) {
- char *name;
+
+/** @return After FilesSetFarourite, this enumerates them. */
+const char *FilesEnumPath(struct Files *const files) {
+ struct Files *f = files;
+ const char *name;
if(!f) return 0;
for( ; f->parent && f->parent->favourite; f = f->parent);
if(!f->favourite) return 0; /* clear favourite, done */
@@ -142,28 +149,32 @@ char *FilesEnumPath(struct Files *f) {
}
/** @return The file name of the selected file. */
-char *FilesName(const struct Files *files) {
+const char *FilesName(const struct Files *const files) {
if(!files || !files->this) return 0;
return files->this->name;
}
+
/** @return File size of the selected file. */
int FilesSize(const struct Files *files) {
if(!files || !files->this) return 0;
return files->this->size;
}
+
/** @return Whether the file is a directory. */
int FilesIsDir(const struct Files *files) {
if(!files || !files->this) return 0;
return files->this->isDir;
}
-/* this is just a list of filenames, (not public) "class File" */
+/* private */
static struct File *File(const char *name, const int size, const int isDir) {
size_t len;
struct File *file;
- if(!name || !*name) { fprintf(stderr, "File: file has no name.\n"); return 0; }
- if((len = strlen(name)) > maxFilename) { fprintf(stderr, "File: file name \"%s\" is too long (%lu.)\n", name, maxFilename); return 0; }
+ if(!name || !*name) { fprintf(stderr, "File: file has no name.\n");
+ return 0; }
+ if((len = strlen(name)) > max_filename) { fprintf(stderr, "File: file name"
+ " \"%s\" is too long (%lu.)\n", name, max_filename); return 0; }
file = malloc(sizeof(struct File) + (len + 1));
if(!file) { File_(file); return 0; }
file->next = 0;
@@ -171,18 +182,18 @@ static struct File *File(const char *name, const int size, const int isDir) {
strncpy(file->name, name, len + 1);
file->size = size;
file->isDir = isDir;
- /* fprintf(stderr, " File(\"%s\" %p)\n", file->name, (void *)file); debug . . . caught bug! */
return file;
}
+
static void File_(struct File *file) {
struct File *next;
/* delete ALL the list of files (not just the one) */
for( ; file; file = next) {
next = file->next;
- /* fprintf(stderr, " File~(\"%s\" %p)...", file->name, (void *)file); fflush(stderr); debug */
free(file);
}
}
+
static int FileInsert(struct File *file, struct File **startAddr) {
struct File *start;
struct File *prev = 0, *ptr = 0;
@@ -191,8 +202,7 @@ static int FileInsert(struct File *file, struct File **startAddr) {
start = (struct File *)*startAddr;
/* 'prev' is where to insert; 'ptr' is next node */
for(prev = 0, ptr = start; ptr; prev = ptr, ptr = ptr->next) {
- /* ansi doesn't have stricmp; strcasecmp not working?
- #define _XOPEN_SOURCE_EXTENDED? or just use strcmp */
+ /* 4.4BSD, POSIX.1-2001 :[ */
if(strcasecmp(file->name, ptr->name) <= 0) break;
}
file->next = ptr;
diff --git a/src/Files.h b/src/Files.h
index 042f15b..165deaa 100644
--- a/src/Files.h
+++ b/src/Files.h
@@ -2,14 +2,14 @@
struct Files;
/** Returns a boolean value. */
-typedef int (*FilesFilter)(const struct Files *, const char *);
+typedef int (*FilesFilter)(struct Files *const, const char *);
-struct Files *Files(const struct Files *parent, const FilesFilter filter);
+struct Files *Files(struct Files *const parent, const FilesFilter filter);
void Files_(struct Files *files);
int FilesAdvance(struct Files *files);
int FilesIsRoot(const struct Files *f);
void FilesSetPath(struct Files *files);
-char *FilesEnumPath(struct Files *files);
-char *FilesName(const struct Files *files);
+const char *FilesEnumPath(struct Files *const files);
+const char *FilesName(const struct Files *const files);
int FilesSize(const struct Files *files);
int FilesIsDir(const struct Files *files);
diff --git a/src/Parser.c b/src/Parser.c
index 7daee66..4a27220 100644
--- a/src/Parser.c
+++ b/src/Parser.c
@@ -36,7 +36,7 @@
@title Parser
@author Neil
@std C89/90
- @version 1.1; 2017-03 fixed pedantic warnings; took out arg
+ @version 1.1; 2017-03 fixed pedantic warnings; command-line improvements
@since 0.6; 2008-03-21 */
#include /* [f]printf FILE */
@@ -58,9 +58,9 @@ struct Parser {
/* private - this is the list of 'widgets', see Widget.c - add widgets to here
to make them recognised - ASCIIbetical */
static const struct Symbol {
- char *symbol;
+ const char *const symbol;
const ParserWidget handler;
- int onlyInRoot; /* fixme: not used, just trust the users? haha */
+ const int onlyInRoot; /* fixme: not used, just trust the users? haha */
} sym[] = {
{ "content", &WidgetContent, 0 }, /* index */
{ "date", &WidgetDate, 0 }, /* news */
@@ -85,10 +85,10 @@ static const struct Symbol {
static const struct Symbol *match(const char *str, const char *end);
/** @return Creates a parser for the string, {str}. */
-struct Parser *Parser(const char *str) {
+struct Parser *Parser(char *const str) {
struct Parser *p;
if(!(p = malloc(sizeof *p))) return 0;
- p->str = (char *)str;
+ p->str = str;
p->pos = p->str;
p->rew = p->str;
p->recursion = 0;
@@ -116,7 +116,7 @@ void ParserRewind(struct Parser *p) {
@param fp: Output.
@fixme This fn needs rewriting; messy.
@fixme Invisible, hack. */
-int ParserParse(struct Parser *p, const struct Files *f, int invisible,
+int ParserParse(struct Parser *p, struct Files *const f, int invisible,
FILE *fp) {
char *mark;
if(!p || !fp || !p->pos) return 0;
diff --git a/src/Parser.h b/src/Parser.h
index aa47c9b..f10f0f5 100644
--- a/src/Parser.h
+++ b/src/Parser.h
@@ -5,10 +5,10 @@ struct Parser;
struct Files;
/** All {ParserWidget}s are in {Widget.c} */
-typedef int (*ParserWidget)(const struct Files *, FILE *fp);
+typedef int (*ParserWidget)(struct Files *const files, FILE *const fp);
-struct Parser *Parser(const char *str);
+struct Parser *Parser(char *const str);
void Parser_(struct Parser **const p_ptr);
void ParserRewind(struct Parser *p);
-int ParserParse(struct Parser *p, const struct Files *f, int invisible,
+int ParserParse(struct Parser *p, struct Files *const f, int invisible,
FILE *fp);
diff --git a/src/Recursor.c b/src/Recursor.c
index bc1242b..348cb1c 100644
--- a/src/Recursor.c
+++ b/src/Recursor.c
@@ -37,8 +37,8 @@
@title Parser
@author Neil
- @std C89/90
- @version 1.1; 2017-03 fixed pedantic warnings; took out arg
+ @std POSIX
+ @version 1.1; 2017-03 fixed pedantic warnings; command-line improvements
@since 1.0; 2016-09-19 Added umask
0.8; 2013-07 case-insensitive sort
0.7; 2012 sth.dsth.d handled properly
@@ -48,16 +48,37 @@
@fixme Encoding is an issue; especially the newsfeed, 7bit.
@fixme It's not robust; eg @(files){@(files){Don't do this.}}. */
-#include /* malloc free fgets */
-#include /* fprintf FILE */
-#include /* strcmp */
-#include /* chdir (POSIX, not ANSI) */
-#include /* umask */
+#include /* malloc free fgets */
+#include /* fprintf FILE */
+#include /* strcmp */
+#include /* chdir (POSIX, not ANSI) */
+#include /* mode_t (umask) */
+#include /* umask */
#include "Files.h"
#include "Widget.h"
#include "Parser.h"
#include "Recursor.h"
+/* constants */
+static const char *const programme = "MakeIndex";
+static const int version_major = 1;
+static const int version_minor = 1;
+
+static const size_t granularity = 1024;
+static const int max_read = 0x1000;
+const char *html_index = "index.html"; /* in multiple files */
+static const char *xml_sitemap = "sitemap.xml";
+static const char *rss_newsfeed = "newsfeed.rss";
+static const char *template_index = ".index.html";
+static const char *template_sitemap = ".sitemap.xml";
+static const char *template_newsfeed = ".newsfeed.rss";
+/* in Files.c */
+extern const char *dir_current;
+extern const char *dir_parent;
+/* in Widget.c */
+extern const char *dot_desc;
+extern const char *dot_news;
+
/* public */
struct Recursor {
char *indexString;
@@ -71,36 +92,24 @@ struct Recursor {
};
/* private */
-int filter(const struct Files *, const char *fn);
-int recurse(const struct Files *parent);
-char *readFile(const char *filename);
-void usage(const char *programme);
-
-/* constants */
-static const int versionMajor = 0;
-static const int versionMinor = 8;
-static const size_t granularity= 1024;
-static const int maxRead = 0x1000;
-const char *htmlIndex = "index.html"; /* in multiple files */
-static const char *xmlSitemap = "sitemap.xml";
-static const char *rssNewsfeed = "newsfeed.rss";
-static const char *tmplIndex = ".index.html";
-static const char *tmplSitemap = ".sitemap.xml";
-static const char *tmplNewsfeed= ".newsfeed.rss";
-/* in Files.c */
-extern const char *dirCurrent;
-extern const char *dirParent;
-/* in Widget.c */
-extern const char *dot_desc;
-extern const char *dot_news;
+static int filter(struct Files *const files, const char *fn);
+static int recurse(struct Files *const parent);
+static char *readFile(const char *filename);
+static void usage(void);
/* there can only be one recursor at a time, sorry */
static struct Recursor *r = 0;
/* public */
+
+/**
+ @param idx: file name of the prototype index file, eg, ".index.html".
+ @param map: file name of the prototype map file, eg, ".sitmap.xml".
+ @param news: file name of the prototype news file, eg, ".newsfeed.rss". */
struct Recursor *Recursor(const char *idx, const char *map, const char *news) {
if(!idx || !idx || !map || !news) return 0;
- if(r) { fprintf(stderr, "Recursor: there is already a Recursor.\n"); return 0; }
+ if(r) { fprintf(stderr, "Recursor: there is already a Recursor.\n");
+ return 0; }
r = malloc(sizeof(struct Recursor));
if(!r) { perror("recursor"); Recursor_(); return 0; }
r->indexString = 0;
@@ -112,52 +121,58 @@ struct Recursor *Recursor(const char *idx, const char *map, const char *news) {
r->newsfeedString = 0;
r->newsfeedParser = 0;
/* open the files for writing (index is opened multiple times in the directories) */
- if(!(r->sitemap = fopen(xmlSitemap, "w"))) perror(xmlSitemap);
- if(!(r->newsfeed = fopen(rssNewsfeed, "w"))) perror(rssNewsfeed);
+ if(!(r->sitemap = fopen(xml_sitemap, "w"))) perror(xml_sitemap);
+ if(!(r->newsfeed = fopen(rss_newsfeed, "w"))) perror(rss_newsfeed);
/* read from the input files */
if( !(r->indexString = readFile(idx))) {
- fprintf(stderr, "Recursor: to make an index, create the file <%s>.\n", idx);
+ fprintf(stderr, "Recursor: to make an index, create the file <%s>.\n",
+ idx);
}
if(r->sitemap && !(r->sitemapString = readFile(map))) {
- fprintf(stderr, "Recursor: to make an sitemap, create the file <%s>.\n", map);
+ fprintf(stderr, "Recursor: to make an sitemap, create the file <%s>.\n",
+ map);
}
if(r->newsfeed && !(r->newsfeedString = readFile(news))) {
- fprintf(stderr, "Recursor: to make a newsfeed, create the file <%s>.\n", news);
+ fprintf(stderr, "Recursor: to make a newsfeed, create the file <%s>.\n",
+ news);
}
/* create Parsers attached to them */
if(r->indexString && !(r->indexParser = Parser(r->indexString))) {
fprintf(stderr, "Recursor: error generating Parser from <%s>.\n", idx);
}
if(r->sitemapString && !(r->sitemapParser = Parser(r->sitemapString))) {
- fprintf(stderr, "Recursor: error generating Parser from <%s>.\n", map);
+ fprintf(stderr, "Recursor: error generating Parser from <%s>.\n", map);
}
if(r->newsfeedString && !(r->newsfeedParser = Parser(r->newsfeedString))) {
fprintf(stderr, "Recursor: error generating Parser from <%s>.\n", news);
}
/* if theirs no content, we have nothing to do */
if(!r->indexParser && !r->sitemapParser && !r->newsfeedParser) {
- fprintf(stderr, "Recursor: no Parsers defined, it would be useless to continue.\n");
+ fprintf(stderr, "Recursor: no Parsers defined, it would be useless to "
+ "continue.\n");
Recursor_();
return 0;
}
/* parse the "header," ie, everything up to ~, the second arg is null
- because we haven't set up the Files, so @files{}, @pwd{}, etc are undefined */
+ because we haven't set up the Files, so @files{}, @pwd{}, etc are
+ undefined */
ParserParse(r->sitemapParser, 0, 0, r->sitemap);
ParserParse(r->newsfeedParser, 0, 0, r->newsfeed);
return r;
}
+
void Recursor_(void) {
if(!r) return;
if(r->sitemapParser && r->sitemap) {
ParserParse(r->sitemapParser, 0, -1, r->sitemap);
ParserParse(r->sitemapParser, 0, 0, r->sitemap);
}
- if(r->sitemap && fclose(r->sitemap)) perror(xmlSitemap);
+ if(r->sitemap && fclose(r->sitemap)) perror(xml_sitemap);
if(r->newsfeedParser && r->newsfeed) {
ParserParse(r->newsfeedParser, 0, -1, r->newsfeed);
ParserParse(r->newsfeedParser, 0, 0, r->newsfeed);
}
- if(r->newsfeed && fclose(r->newsfeed)) perror(rssNewsfeed);
+ if(r->newsfeed && fclose(r->newsfeed)) perror(rss_newsfeed);
Parser_(&r->indexParser);
free(r->indexString);
Parser_(&r->sitemapParser);
@@ -168,33 +183,23 @@ void Recursor_(void) {
r = 0;
}
-/* entry-point (shouldn't have a prototype) */
-int main(int argc, char **argv) {
- int ret;
-
- /* set up; fixme: dangerous! use stdarg, have a -delete, -write, and -help */
- if(argc <= 1) { usage(argv[0]); return EXIT_SUCCESS; }
- fprintf(stderr, "Changing directory to <%s>.\n", argv[1]);
- if(chdir(argv[1])) { perror(argv[1]); return EXIT_FAILURE; }
-
- /* make sure that umask is set so that others can read what we create */
- umask((mode_t)(S_IWGRP | S_IWOTH));
-
- /* recursing; fixme: this should be configurable */
- if(!Recursor(tmplIndex, tmplSitemap, tmplNewsfeed)) return EXIT_FAILURE;
- ret = recurse(0);
- Recursor_();
- return ret ? EXIT_SUCCESS : EXIT_FAILURE;
+/** Actually does the recursion. */
+int RecursorGo(void) {
+ if(!r) return 0;
+ return recurse(0);
}
/* private */
-int filter(const struct Files *files, const char *fn) {
- char *str, filed[64];
+/** @implements FilesFilter */
+static int filter(struct Files *const files, const char *fn) {
+ const char *str;
+ char filed[64];
FILE *fd;
- if(!r) { fprintf(stderr, "Recusor::filter: recursor not initialised.\n"); return 0; }
+ if(!r) { fprintf(stderr, "Recusor::filter: recursor not initialised.\n");
+ return 0; }
/* *.d[.0]* */
- for(str = (char *)fn; (str = strstr(str, dot_desc)); ) {
+ for(str = fn; (str = strstr(str, dot_desc)); ) {
str += strlen(dot_desc);
if(*str == '\0' || *str == '.') return 0;
}
@@ -211,11 +216,11 @@ int filter(const struct Files *files, const char *fn) {
}
}
/* . */
- if(!strcmp(fn, dirCurrent)) return 0;
+ if(!strcmp(fn, dir_current)) return 0;
/* .. */
- if(!strcmp(fn, dirParent) && FilesIsRoot(files)) return 0;
+ if(!strcmp(fn, dir_parent) && FilesIsRoot(files)) return 0;
/* index.html */
- if(!strcmp(fn, htmlIndex)) return 0;
+ if(!strcmp(fn, html_index)) return 0;
/* add .d, check 1 line for \n (hmm, this must be a real time waster) */
if(strlen(fn) > sizeof(filed) - strlen(dot_desc) - 1) {
fprintf(stderr, "Recusor::filter: regected '%s' because it was too long (%d.)\n", fn, (int)sizeof(filed));
@@ -233,17 +238,18 @@ int filter(const struct Files *files, const char *fn) {
}
return -1;
}
-int recurse(const struct Files *parent) {
+
+static int recurse(struct Files *const parent) {
struct Files *f;
- char *name;
+ const char *name;
FILE *fp;
f = Files(parent, &filter);
/* write the index */
- if((fp = fopen(htmlIndex, "w"))) {
+ if((fp = fopen(html_index, "w"))) {
ParserParse(r->indexParser, f, 0, fp);
ParserRewind(r->indexParser);
fclose(fp);
- } else perror(htmlIndex);
+ } else perror(html_index);
/* sitemap */
ParserParse(r->sitemapParser, f, 0, r->sitemap);
ParserRewind(r->sitemapParser);
@@ -251,18 +257,19 @@ int recurse(const struct Files *parent) {
while(FilesAdvance(f)) {
if(!FilesIsDir(f) ||
!(name = FilesName(f)) ||
- !strcmp(dirCurrent, name) ||
- !strcmp(dirParent, name) ||
+ !strcmp(dir_current, name) ||
+ !strcmp(dir_parent, name) ||
!(name = FilesName(f))) continue;
if(chdir(name)) { perror(name); continue; }
recurse(f);
/* this happens on Windows; I don't know what to do */
- if(chdir(dirParent)) perror(dirParent);
+ if(chdir(dir_parent)) perror(dir_parent);
}
Files_(f);
return -1;
}
-char *readFile(const char *filename) {
+
+static char *readFile(const char *filename) {
char *buf = 0, *newBuf;
size_t bufPos = 0, bufSize = 0, rd;
FILE *fp;
@@ -281,16 +288,61 @@ char *readFile(const char *filename) {
if(fclose(fp)) perror(filename);
return buf; /** you must free() the memory! */
}
-void usage(const char *programme) {
- fprintf(stderr, "Usage: %s \n\n", programme);
- fprintf(stderr, "Version %d.%d.\n\n", versionMajor, versionMinor);
- fprintf(stderr, "MakeIndex is a content generator that places a changing\n");
- fprintf(stderr, "index.html on all the directories under \n");
- fprintf(stderr, "based on a template file in called <%s>.\n", tmplIndex);
- fprintf(stderr, "It also does some other stuff.\n\n");
- fprintf(stderr, "See readme.txt or http://neil.chaosnet.org/ for further info.\n\n");
- fprintf(stderr, "MakeIndex Copyright 2008, 2012 Neil Edelman\n");
- fprintf(stderr, "This program comes with ABSOLUTELY NO WARRANTY.\n");
- fprintf(stderr, "This is free software, and you are welcome to redistribute it\n");
- fprintf(stderr, "under certain conditions; see gpl.txt.\n\n");
+
+static void usage(void) {
+ fprintf(stderr, "Usage: %s [--directory|-d] | [--help|-h]\n\n"
+ "Version %d.%d.\n\n"
+ "MakeIndex is a content management system that generates static\n"
+ "content, (mostly index.html,) on all the directories rooted at the\n"
+ " based on <%s>.\n\n"
+ "It also does some other stuff. See readme.txt or\n"
+ "http://neil.chaosnet.org/ for further info.\n\n", programme,
+ version_major, version_minor, template_index);
+ fprintf(stderr, "MakeIndex Copyright 2008, 2012 Neil Edelman\n"
+ "This program comes with ABSOLUTELY NO WARRANTY.\n"
+ "This is free software, and you are welcome to redistribute it\n"
+ "under certain conditions; see gpl.txt.\n\n");
+}
+
+/* entry-point (shouldn't have a prototype) */
+int main(int argc, char **argv) {
+ int ac, ret;
+ int is_help = 0, is_invalid = 0;
+ const char *directory = 0;
+
+ /* gperf is wonderful, but what about other build systems? */
+ for(ac = 1; ac < argc; ac++) {
+ const char *const av = argv[ac];
+ if(!strcmp("--help", av) || !strcmp("-h", av)) {
+ is_help = -1;
+ } else if(!strcmp("--directory", av) || !strcmp("-d", av)) {
+ if(directory) {
+ break;
+ } else if(++ac < argc) {
+ directory = argv[ac];
+ } else {
+ is_invalid = -1; break;
+ }
+ }
+ }
+
+ if(is_help || !directory) {
+ usage();
+ return is_help ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+
+ fprintf(stderr, "Changing directory to <%s>.\n", directory);
+ if(chdir(directory)) { perror(directory); return EXIT_FAILURE; }
+
+ /* make sure that umask is set so that others can read what we create
+ "warning: passing argument 1 of 'umask' with different width due to
+ prototype" <- umask's fault; can't change? */
+ umask(S_IWGRP | S_IWOTH);
+
+ /* recursing; fixme: this should be configurable */
+ if(!Recursor(template_index, template_sitemap, template_newsfeed))
+ return EXIT_FAILURE;
+ ret = RecursorGo();
+ Recursor_();
+ return ret ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/Recursor.h b/src/Recursor.h
index 0ee0e5c..c40a2ca 100644
--- a/src/Recursor.h
+++ b/src/Recursor.h
@@ -1,4 +1,6 @@
+/** See \see{Recursor}. */
struct Recursor;
struct Recursor *Recursor(const char *index, const char *map, const char *news);
void Recursor_(void);
+int RecursorGo(void);
diff --git a/src/Widget.c b/src/Widget.c
index 04c0559..d5244a1 100644
--- a/src/Widget.c
+++ b/src/Widget.c
@@ -11,7 +11,7 @@
@title Widget
@author Neil
@std C89/90
- @version 1.1; 2017-03 fixed pedantic warnings; took out arg
+ @version 1.1; 2017-03 fixed pedantic warnings; command-line improvements
@since 0.6; 2008-03-25 */
#include /* strncat strncpy */
@@ -36,17 +36,17 @@
/* ugly --> */
/* constants */
-static const char *htmlDesc = "index.d";
-static const char *htmlContent = "content.d";
-static const char *separator = "/";
-static const char *picture = ".jpeg"; /* yeah, I hard coded this */
-static const size_t maxRead = 512;
-static const char *dot_link = ".link";
-const char *dot_desc = ".d"; /* used in multiple files */
-const char *dot_news = ".news";
-extern const char *dirCurrent;
-extern const char *dirParent;
-extern const char *htmlIndex;
+static const char *html_desc = "index.d";
+static const char *html_content = "content.d";
+static const char *separator = "/";
+static const char *picture = ".jpeg"; /* yeah, I hard coded this */
+static const size_t max_read = 512;
+static const char *dot_link = ".link";
+const char *dot_desc = ".d"; /* used in multiple files */
+const char *dot_news = ".news";
+extern const char *dir_current;
+extern const char *dir_parent;
+extern const char *html_index;
/* global, ick: news */
static int year = 1983;
@@ -92,7 +92,7 @@ int WidgetSetNews(const char *fn) {
/* the widget handlers */
/** @implements ParserWidget */
-int WidgetContent(const struct Files *f, FILE *fp) {
+int WidgetContent(struct Files *const f, FILE *const fp) {
char buf[81], *bufpos;
size_t i;
FILE *in;
@@ -103,37 +103,38 @@ int WidgetContent(const struct Files *f, FILE *fp) {
but we have to not translate already encoded html; the only solution that
a could see is have a new langauge (like-LaTeX) that gracefully handles
plain-text */
- if((in = fopen(htmlContent, "r")) || (in = fopen(htmlDesc, "r"))) {
- for(i = 0; (i < maxRead)
+ if((in = fopen(html_content, "r")) || (in = fopen(html_desc, "r"))) {
+ for(i = 0; (i < max_read)
&& (bufpos = fgets(buf, (int)sizeof(buf), in)); i++) {
fprintf(fp, "%s", bufpos);
}
- if(fclose(in)) perror(htmlDesc);
+ if(fclose(in)) perror(html_desc);
}
return 0;
}
/** @implements ParserWidget */
-int WidgetDate(const struct Files *f, FILE *fp) {
+int WidgetDate(struct Files *const f, FILE *const fp) {
UNUSED(f);
/* ISO 8601 - YYYY-MM-DD */
fprintf(fp, "%4.4d-%2.2d-%2.2d", year, month, day);
return 0;
}
/** @implements ParserWidget */
-int WidgetFilealt(const struct Files *f, FILE *fp) {
+int WidgetFilealt(struct Files *const f, FILE *const fp) {
fprintf(fp, "%s", FilesIsDir(f) ? "Dir" : "File");
return 0;
}
/** @implements ParserWidget */
-int WidgetFiledesc(const struct Files *f, FILE *fp) {
- char buf[256], *name;
+int WidgetFiledesc(struct Files *const f, FILE *const fp) {
+ char buf[256];
+ const char *name;
FILE *in;
if(!(name = FilesName(f))) return 0;
if(FilesIsDir(f)) {
/* /index.d */
strncpy(buf, name, sizeof(buf) - 9);
strncat(buf, separator, 1lu);
- strncat(buf, htmlDesc, 7lu);
+ strncat(buf, html_desc, 7lu);
} else {
/* .d */
strncpy(buf, name, sizeof(buf) - 6);
@@ -142,7 +143,7 @@ int WidgetFiledesc(const struct Files *f, FILE *fp) {
if((in = fopen(buf, "r"))) {
char *bufpos;
size_t i;
- for(i = 0; (i < maxRead)
+ for(i = 0; (i < max_read)
&& (bufpos = fgets(buf, (int)sizeof(buf), in)); i++) {
fprintf(fp, "%s", bufpos);
}
@@ -151,8 +152,8 @@ int WidgetFiledesc(const struct Files *f, FILE *fp) {
return 0;
}
/** @implements ParserWidget */
-int WidgetFilehref(const struct Files *f, FILE *fp) {
- char *str, *name;
+int WidgetFilehref(struct Files *const f, FILE *const fp) {
+ const char *str, *name;
int ch;
FILE *fhref;
if(!(name = FilesName(f))) return 0;
@@ -171,8 +172,9 @@ int WidgetFilehref(const struct Files *f, FILE *fp) {
return 0;
}
/** @implements ParserWidget */
-int WidgetFileicon(const struct Files *f, FILE *fp) {
- char buf[256], *name;
+int WidgetFileicon(struct Files *const f, FILE *const fp) {
+ char buf[256];
+ const char *name;
FILE *in;
if(!(name = FilesName(f))) return 0;
/* insert .d.jpeg if available */
@@ -188,29 +190,29 @@ int WidgetFileicon(const struct Files *f, FILE *fp) {
as having a @root{/} */
FilesSetPath((struct Files *)f);
while(FilesEnumPath((struct Files *)f)) {
- fprintf(fp, "%s%s", dirParent, separator);
+ fprintf(fp, "%s%s", dir_parent, separator);
}
fprintf(fp, "%s%s", FilesIsDir(f) ? "dir" : "file", picture);
}
return 0;
}
/** @implements ParserWidget */
-int WidgetFilename(const struct Files *f, FILE *fp) {
+int WidgetFilename(struct Files *const f, FILE *const fp) {
fprintf(fp, "%s", FilesName(f));
return 0;
}
/** @implements ParserWidget */
-int WidgetFiles(const struct Files *f, FILE *fp) {
+int WidgetFiles(struct Files *const f, FILE *const fp) {
while(0 && fp);
return FilesAdvance((struct Files *)f) ? -1 : 0;
}
/** @implements ParserWidget */
-int WidgetFilesize(const struct Files *f, FILE *fp) { /* eww */
+int WidgetFilesize(struct Files *const f, FILE *const fp) { /* eww */
if(!FilesIsDir(f)) fprintf(fp, " (%d KB)", FilesSize(f));
return 0;
}
/** @implements ParserWidget */
-int WidgetNews(const struct Files *f, FILE *fp) {
+int WidgetNews(struct Files *const f, FILE *const fp) {
char buf[256], *bufpos;
size_t i;
FILE *in;
@@ -218,20 +220,21 @@ int WidgetNews(const struct Files *f, FILE *fp) {
UNUSED(f);
if(!filenews[0]) return 0;
if(!(in = fopen(filenews, "r"))) { perror(filenews); return 0; }
- for(i = 0; (i < maxRead)&&(bufpos = fgets(buf, (int)sizeof(buf), in)); i++){
+ for(i = 0; (i < max_read) && (bufpos = fgets(buf, (int)sizeof(buf), in));
+ i++){
fprintf(fp, "%s", bufpos);
}
if(fclose(in)) perror(filenews);
return 0;
}
/** @implements ParserWidget */
-int WidgetNewsname(const struct Files *f, FILE *fp) {
+int WidgetNewsname(struct Files *const f, FILE *const fp) {
UNUSED(f);
fprintf(fp, "%s", filenews);
return 0;
}
/** @implements ParserWidget */
-int WidgetNow(const struct Files *f, FILE *fp) {
+int WidgetNow(struct Files *const f, FILE *const fp) {
char t[22];
time_t currentTime;
struct tm *formatedTime;
@@ -245,27 +248,27 @@ int WidgetNow(const struct Files *f, FILE *fp) {
return 0;
}
/** @implements ParserWidget */
-int WidgetPwd(const struct Files *f, FILE *fp) {
+int WidgetPwd(struct Files *const f, FILE *const fp) {
static int persistant = 0; /* ick, be very careful! */
- char *pwd;
+ const char *pwd;
if(!persistant) { persistant = -1; FilesSetPath((struct Files *)f); }
- pwd = FilesEnumPath((struct Files *)f);
+ pwd = FilesEnumPath(f);
if(!pwd) { persistant = 0; return 0; }
fprintf(fp, "%s", pwd);
return -1;
}
/** @implements ParserWidget */
-int WidgetRoot(const struct Files *f, FILE *fp) {
+int WidgetRoot(struct Files *const f, FILE *const fp) {
static int persistant = 0; /* ick, be very careful! */
- char *pwd;
+ const char *pwd;
if(!persistant) { persistant = -1; FilesSetPath((struct Files *)f); }
- pwd = FilesEnumPath((struct Files *)f);
+ pwd = FilesEnumPath(f);
if(!pwd) { persistant = 0; return 0; }
- fprintf(fp, "%s", dirParent);
+ fprintf(fp, "%s", dir_parent);
return -1;
}
/** @implements ParserWidget */
-int WidgetTitle(const struct Files *f, FILE *fp) {
+int WidgetTitle(struct Files *const f, FILE *const fp) {
UNUSED(f);
fprintf(fp, "%s", title);
return 0;
diff --git a/src/Widget.h b/src/Widget.h
index e46325f..43a9c4b 100644
--- a/src/Widget.h
+++ b/src/Widget.h
@@ -4,18 +4,18 @@ struct Files;
void WidgetSetRecursor(const struct Recursor *recursor);
int WidgetSetNews(const char *fn);
/* the widget handlers */
-int WidgetDate(const struct Files *f, FILE *fp);
-int WidgetContent(const struct Files *f, FILE *fp);
-int WidgetFilealt(const struct Files *f, FILE *fp);
-int WidgetFiledesc(const struct Files *f, FILE *fp);
-int WidgetFilehref(const struct Files *f, FILE *fp);
-int WidgetFileicon(const struct Files *f, FILE *fp);
-int WidgetFilename(const struct Files *f, FILE *fp);
-int WidgetFiles(const struct Files *f, FILE *fp);
-int WidgetFilesize(const struct Files *f, FILE *fp);
-int WidgetNews(const struct Files *f, FILE *fp);
-int WidgetNewsname(const struct Files *f, FILE *fp);
-int WidgetNow(const struct Files *f, FILE *fp);
-int WidgetPwd(const struct Files *f, FILE *fp);
-int WidgetRoot(const struct Files *f, FILE *fp);
-int WidgetTitle(const struct Files *f, FILE *fp);
+int WidgetDate(struct Files *const f, FILE *const fp);
+int WidgetContent(struct Files *const f, FILE *const fp);
+int WidgetFilealt(struct Files *const f, FILE *const fp);
+int WidgetFiledesc(struct Files *const f, FILE *const fp);
+int WidgetFilehref(struct Files *const f, FILE *const fp);
+int WidgetFileicon(struct Files *const f, FILE *const fp);
+int WidgetFilename(struct Files *const f, FILE *const fp);
+int WidgetFiles(struct Files *const f, FILE *const fp);
+int WidgetFilesize(struct Files *const f, FILE *const fp);
+int WidgetNews(struct Files *const f, FILE *const fp);
+int WidgetNewsname(struct Files *const f, FILE *const fp);
+int WidgetNow(struct Files *const f, FILE *const fp);
+int WidgetPwd(struct Files *const f, FILE *const fp);
+int WidgetRoot(struct Files *const f, FILE *const fp);
+int WidgetTitle(struct Files *const f, FILE *const fp);