diff --git a/doc/Files.html b/doc/Files.html index 0d7ba02..4cfb7a0 100644 --- a/doc/Files.html +++ b/doc/Files.html @@ -50,11 +50,11 @@ a relation to other Files by 'parent' and 'favourite' (@(pwd) uses this.)

minimum standard
-
C89/90
+
POSIX
author
Neil
version
-
1.1; 2017-03 fixed pedantic warnings; took out arg
+
1.1; 2017-03 fixed pedantic warnings; command-line improvements
since
0.6; 2008-03-24
@@ -72,9 +72,9 @@ See Files. -
-

typedef int (*FilesFilter)(const struct Files *, const char *)

-
typedef int (*FilesFilter)(const struct Files *, const char *)
+
+

typedef int (*FilesFilter)(struct Files *const, const char *)

+
typedef int (*FilesFilter)(struct Files *const, const char *)

Returns a boolean value.

@@ -90,7 +90,7 @@ Returns a boolean value. struct Files * Files - const struct Files *parent, const FilesFilter filter + struct Files *const parent, const FilesFilter filter void @@ -113,14 +113,14 @@ Returns a boolean value. struct Files *f - char * + const char * FilesEnumPath - struct Files *f + struct Files *const files - char * + const char * FilesName - const struct Files *files + const struct Files *const files int @@ -139,11 +139,16 @@ Returns a boolean value.

Files

-
struct Files * Files (const struct Files *parent, const FilesFilter filter)
+
struct Files * Files (struct Files *const parent, const FilesFilter filter)

-parent->this must be the 'file' (directory) that you want to create +Directory information.

+
parameter: parent
+
parent->this must be the 'file' (directory) that you want to + create.
+
parameter: filter
+
This returns true on the files that you want included.
@@ -189,17 +194,16 @@ Resets the list of favourites.

FilesEnumPath

-
char * FilesEnumPath (struct Files *f)
-

-After FilesSetFarourite, this enumerates them. -

+
const char * FilesEnumPath (struct Files *const files)
+
return
+
After FilesSetFarourite, this enumerates them.

FilesName

-
char * FilesName (const struct Files *files)
+
const char * FilesName (const struct Files *const files)
return
The file name of the selected file.
diff --git a/doc/Parser.html b/doc/Parser.html index befce96..94e5c8e 100644 --- a/doc/Parser.html +++ b/doc/Parser.html @@ -65,9 +65,9 @@ Dependancy on Files
-
-

typedef int (*ParserWidget)(const struct Files *, FILE *fp)

-
typedef int (*ParserWidget)(const struct Files *, FILE *fp)
+
+

typedef int (*ParserWidget)(struct Files *const files, FILE *const fp)

+
typedef int (*ParserWidget)(struct Files *const files, FILE *const fp)

All ParserWidgets are in Widget.c

@@ -83,7 +83,7 @@ All ParserWidgets are in Widget.c struct Parser * Parser - const char *str + char *const str void @@ -98,7 +98,7 @@ All ParserWidgets are in Widget.c int ParserParse - struct Parser *p, const struct Files *f, int invisible, + struct Parser *p, struct Files *const f, int invisible, FILE *fp @@ -108,7 +108,7 @@ All ParserWidgets are in Widget.c

Parser

-
struct Parser * Parser (const char *str)
+
struct Parser * Parser (char *const str)
return
Creates a parser for the string, str.
@@ -136,7 +136,7 @@ Resets the parser, p.

ParserParse

-
int ParserParse (struct Parser *p, const struct Files *f, int invisible,
+
int ParserParse (struct Parser *p, struct Files *const f, int invisible,
 	FILE *fp)

Parse, called recursively. diff --git a/doc/Recursor.html b/doc/Recursor.html index 04aa1a4..df2e430 100644 --- a/doc/Recursor.html +++ b/doc/Recursor.html @@ -102,11 +102,11 @@ If this is not the case, the constants are in Files.c.

minimum standard
-
C89/90
+
POSIX
author
Neil
version
-
1.1; 2017-03 fixed pedantic warnings; took out arg
+
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 @@ -125,26 +125,71 @@ If this is not the case, the constants are in Files.c.

Declarations

+
+

struct Recursor

+
struct Recursor
+

+See Recursor. +

+
+
+
+

Function Summary

+ + + + + + + + + + + +static void - +
Return TypeFunction NameArgument List
struct Recursor *Recursorconst char *idx, const char *map, const char *news
intRecursorGovoid
} -void usageconst char *programmevoid

Function Detail

+
+

Recursor

+
struct Recursor * Recursor (const char *idx, const char *map, const char *news)
+
+
parameter: idx
+
file name of the prototype index file, eg, ".index.html".
+
parameter: map
+
file name of the prototype map file, eg, ".sitmap.xml".
+
parameter: news
+
file name of the prototype news file, eg, ".newsfeed.rss".
+
+
+ +
+

RecursorGo

+
int RecursorGo (void)
+

+Actually does the recursion. +

+
+
+
+

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);