Fixed pedantic warnings.

master
Neil Edelman 6 years ago
parent 7613e60e86
commit 4eba349541

@ -50,11 +50,11 @@ a relation to other Files by 'parent' and 'favourite' (@(pwd) uses this.)
</p>
<dl>
<dt>minimum standard</dt>
<dd>C89/90</dd>
<dd>POSIX</dd>
<dt>author</dt>
<dd>Neil</dd>
<dt>version</dt>
<dd>1.1; 2017-03 fixed pedantic warnings; took out arg</dd>
<dd>1.1; 2017-03 fixed pedantic warnings; command-line improvements</dd>
<dt>since</dt>
<dd>0.6; 2008-03-24</dd>
</dl>
@ -72,9 +72,9 @@ See <a href = "#Files">Files</a>.
</dl>
</div>
<div><a name = "typedef int (*FilesFilter)(const struct Files *, const char *)"><!-- --></a>
<h3>typedef int (*FilesFilter)(const struct Files *, const char *)</h3>
<pre><b>typedef int (*FilesFilter)(const struct Files *, const char *)</b></pre>
<div><a name = "typedef int (*FilesFilter)(struct Files *const, const char *)"><!-- --></a>
<h3>typedef int (*FilesFilter)(struct Files *const, const char *)</h3>
<pre><b>typedef int (*FilesFilter)(struct Files *const, const char *)</b></pre>
<p>
Returns a boolean value.
</p>
@ -90,7 +90,7 @@ Returns a boolean value.
<tr>
<td>struct Files *</td>
<td><a href = "#Files">Files</a></td>
<td>const struct Files *parent, const FilesFilter filter</td>
<td>struct Files *const parent, const FilesFilter filter</td>
</tr>
<tr>
<td>void</td>
@ -113,14 +113,14 @@ Returns a boolean value.
<td>struct Files *f</td>
</tr>
<tr>
<td>char *</td>
<td>const char *</td>
<td><a href = "#FilesEnumPath">FilesEnumPath</a></td>
<td>struct Files *f</td>
<td>struct Files *const files</td>
</tr>
<tr>
<td>char *</td>
<td>const char *</td>
<td><a href = "#FilesName">FilesName</a></td>
<td>const struct Files *files</td>
<td>const struct Files *const files</td>
</tr>
<tr>
<td>int</td>
@ -139,11 +139,16 @@ Returns a boolean value.
<div><a name = "Files"><!-- --></a>
<h3>Files</h3>
<pre>struct Files * <b>Files</b> (const struct Files *parent, const FilesFilter filter)</pre>
<pre>struct Files * <b>Files</b> (struct Files *const parent, const FilesFilter filter)</pre>
<p>
parent-&gt;this must be the 'file' (directory) that you want to create
Directory information.
</p>
<dl>
<dt>parameter: parent</dt>
<dd><em>parent-&gt;this</em> must be the 'file' (directory) that you want to
create.</dd>
<dt>parameter: filter</dt>
<dd>This returns true on the files that you want included.</dd>
</dl>
</div>
@ -189,17 +194,16 @@ Resets the list of favourites.
<div><a name = "FilesEnumPath"><!-- --></a>
<h3>FilesEnumPath</h3>
<pre>char * <b>FilesEnumPath</b> (struct Files *f)</pre>
<p>
After FilesSetFarourite, this enumerates them.
</p>
<pre>const char * <b>FilesEnumPath</b> (struct Files *const files)</pre>
<dl>
<dt>return</dt>
<dd>After FilesSetFarourite, this enumerates them.</dd>
</dl>
</div>
<div><a name = "FilesName"><!-- --></a>
<h3>FilesName</h3>
<pre>char * <b>FilesName</b> (const struct Files *files)</pre>
<pre>const char * <b>FilesName</b> (const struct Files *const files)</pre>
<dl>
<dt>return</dt>
<dd>The file name of the selected file.</dd>

@ -65,9 +65,9 @@ Dependancy on <em>Files</em>
</dl>
</div>
<div><a name = "typedef int (*ParserWidget)(const struct Files *, FILE *fp)"><!-- --></a>
<h3>typedef int (*ParserWidget)(const struct Files *, FILE *fp)</h3>
<pre><b>typedef int (*ParserWidget)(const struct Files *, FILE *fp)</b></pre>
<div><a name = "typedef int (*ParserWidget)(struct Files *const files, FILE *const fp)"><!-- --></a>
<h3>typedef int (*ParserWidget)(struct Files *const files, FILE *const fp)</h3>
<pre><b>typedef int (*ParserWidget)(struct Files *const files, FILE *const fp)</b></pre>
<p>
All <em>ParserWidget</em>s are in <em>Widget.c</em>
</p>
@ -83,7 +83,7 @@ All <em>ParserWidget</em>s are in <em>Widget.c</em>
<tr>
<td>struct Parser *</td>
<td><a href = "#Parser">Parser</a></td>
<td>const char *str</td>
<td>char *const str</td>
</tr>
<tr>
<td>void</td>
@ -98,7 +98,7 @@ All <em>ParserWidget</em>s are in <em>Widget.c</em>
<tr>
<td>int</td>
<td><a href = "#ParserParse">ParserParse</a></td>
<td>struct Parser *p, const struct Files *f, int invisible,
<td>struct Parser *p, struct Files *const f, int invisible,
FILE *fp</td>
</tr>
</table>
@ -108,7 +108,7 @@ All <em>ParserWidget</em>s are in <em>Widget.c</em>
<div><a name = "Parser"><!-- --></a>
<h3>Parser</h3>
<pre>struct Parser * <b>Parser</b> (const char *str)</pre>
<pre>struct Parser * <b>Parser</b> (char *const str)</pre>
<dl>
<dt>return</dt>
<dd>Creates a parser for the string, <em>str</em>.</dd>
@ -136,7 +136,7 @@ Resets the parser, <em>p</em>.
<div><a name = "ParserParse"><!-- --></a>
<h3>ParserParse</h3>
<pre>int <b>ParserParse</b> (struct Parser *p, const struct Files *f, int invisible,
<pre>int <b>ParserParse</b> (struct Parser *p, struct Files *const f, int invisible,
FILE *fp)</pre>
<p>
Parse, called recursively.

@ -102,11 +102,11 @@ If this is not the case, the constants are in <em>Files.c</em>.
</p>
<dl>
<dt>minimum standard</dt>
<dd>C89/90</dd>
<dd>POSIX</dd>
<dt>author</dt>
<dd>Neil</dd>
<dt>version</dt>
<dd>1.1; 2017-03 fixed pedantic warnings; took out arg</dd>
<dd>1.1; 2017-03 fixed pedantic warnings; command-line improvements</dd>
<dt>since</dt>
<dd>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 <em>Files.c</em>.
<a name = "_declarations"><!-- --></a><h2>Declarations</h2>
<div><a name = "struct Recursor"><!-- --></a>
<h3>struct Recursor</h3>
<pre><b>struct Recursor</b></pre>
<p>
See <a href = "#Recursor">Recursor</a>.
</p>
<dl>
</dl>
</div>
<a name = "_summary"><!-- --></a><h2>Function Summary</h2>
<table>
<tr><th>Return Type</th><th>Function Name</th><th>Argument List</th></tr>
<tr>
<td>struct Recursor *</td>
<td><a href = "#Recursor">Recursor</a></td>
<td>const char *idx, const char *map, const char *news</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#RecursorGo">RecursorGo</a></td>
<td>void</td>
</tr>
<tr>
<td>}
void</td>
static void</td>
<td><a href = "#usage">usage</a></td>
<td>const char *programme</td>
<td>void</td>
</tr>
</table>
<a name = "_detail"><!-- --></a><h2>Function Detail</h2>
<div><a name = "Recursor"><!-- --></a>
<h3>Recursor</h3>
<pre>struct Recursor * <b>Recursor</b> (const char *idx, const char *map, const char *news)</pre>
<dl>
<dt>parameter: idx</dt>
<dd>file name of the prototype index file, eg, ".index.html".</dd>
<dt>parameter: map</dt>
<dd>file name of the prototype map file, eg, ".sitmap.xml".</dd>
<dt>parameter: news</dt>
<dd>file name of the prototype news file, eg, ".newsfeed.rss".</dd>
</dl>
</div>
<div><a name = "RecursorGo"><!-- --></a>
<h3>RecursorGo</h3>
<pre>int <b>RecursorGo</b> (void)</pre>
<p>
Actually does the recursion.
</p>
<dl>
</dl>
</div>
<div><a name = "usage"><!-- --></a>
<h3>usage</h3>
<pre>}
void <b>usage</b> (const char *programme)</pre>
static void <b>usage</b> (void)</pre>
<p>
you must free() the memory!
</p>

@ -53,77 +53,77 @@
<tr>
<td>int</td>
<td><a href = "#WidgetContent">WidgetContent</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetDate">WidgetDate</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetFilealt">WidgetFilealt</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetFiledesc">WidgetFiledesc</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetFilehref">WidgetFilehref</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetFileicon">WidgetFileicon</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetFilename">WidgetFilename</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetFiles">WidgetFiles</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetFilesize">WidgetFilesize</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetNews">WidgetNews</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetNewsname">WidgetNewsname</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetNow">WidgetNow</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetPwd">WidgetPwd</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetRoot">WidgetRoot</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
<tr>
<td>int</td>
<td><a href = "#WidgetTitle">WidgetTitle</a></td>
<td>const struct Files *f, FILE *fp</td>
<td>struct Files *const f, FILE *const fp</td>
</tr>
</table>
@ -132,7 +132,7 @@
<div><a name = "WidgetContent"><!-- --></a>
<h3>WidgetContent</h3>
<pre>int <b>WidgetContent</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetContent</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -141,7 +141,7 @@
<div><a name = "WidgetDate"><!-- --></a>
<h3>WidgetDate</h3>
<pre>int <b>WidgetDate</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetDate</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -150,7 +150,7 @@
<div><a name = "WidgetFilealt"><!-- --></a>
<h3>WidgetFilealt</h3>
<pre>int <b>WidgetFilealt</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetFilealt</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -159,7 +159,7 @@
<div><a name = "WidgetFiledesc"><!-- --></a>
<h3>WidgetFiledesc</h3>
<pre>int <b>WidgetFiledesc</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetFiledesc</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -168,7 +168,7 @@
<div><a name = "WidgetFilehref"><!-- --></a>
<h3>WidgetFilehref</h3>
<pre>int <b>WidgetFilehref</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetFilehref</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -177,7 +177,7 @@
<div><a name = "WidgetFileicon"><!-- --></a>
<h3>WidgetFileicon</h3>
<pre>int <b>WidgetFileicon</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetFileicon</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -186,7 +186,7 @@
<div><a name = "WidgetFilename"><!-- --></a>
<h3>WidgetFilename</h3>
<pre>int <b>WidgetFilename</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetFilename</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -195,7 +195,7 @@
<div><a name = "WidgetFiles"><!-- --></a>
<h3>WidgetFiles</h3>
<pre>int <b>WidgetFiles</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetFiles</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -204,7 +204,7 @@
<div><a name = "WidgetFilesize"><!-- --></a>
<h3>WidgetFilesize</h3>
<pre>int <b>WidgetFilesize</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetFilesize</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -213,7 +213,7 @@
<div><a name = "WidgetNews"><!-- --></a>
<h3>WidgetNews</h3>
<pre>int <b>WidgetNews</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetNews</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -222,7 +222,7 @@
<div><a name = "WidgetNewsname"><!-- --></a>
<h3>WidgetNewsname</h3>
<pre>int <b>WidgetNewsname</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetNewsname</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -231,7 +231,7 @@
<div><a name = "WidgetNow"><!-- --></a>
<h3>WidgetNow</h3>
<pre>int <b>WidgetNow</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetNow</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -240,7 +240,7 @@
<div><a name = "WidgetPwd"><!-- --></a>
<h3>WidgetPwd</h3>
<pre>int <b>WidgetPwd</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetPwd</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -249,7 +249,7 @@
<div><a name = "WidgetRoot"><!-- --></a>
<h3>WidgetRoot</h3>
<pre>int <b>WidgetRoot</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetRoot</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>
@ -258,7 +258,7 @@
<div><a name = "WidgetTitle"><!-- --></a>
<h3>WidgetTitle</h3>
<pre>int <b>WidgetTitle</b> (const struct Files *f, FILE *fp)</pre>
<pre>int <b>WidgetTitle</b> (struct Files *const f, FILE *const fp)</pre>
<dl>
<dt>implements</dt>
<dd>ParserWidget</dd>

@ -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 <stdlib.h> /* 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;

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

@ -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 <stdio.h> /* [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;

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

@ -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 <stdlib.h> /* malloc free fgets */
#include <stdio.h> /* fprintf FILE */
#include <string.h> /* strcmp */
#include <unistd.h> /* chdir (POSIX, not ANSI) */
#include <sys/stat.h> /* umask */
#include <stdlib.h> /* malloc free fgets */
#include <stdio.h> /* fprintf FILE */
#include <string.h> /* strcmp */
#include <unistd.h> /* chdir (POSIX, not ANSI) */
#include <sys/types.h> /* mode_t (umask) */
#include <sys/stat.h> /* 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 <directory>\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 <directory>\n");
fprintf(stderr, "based on a template file in <directory> 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] <directory> | [--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"
"<directory> 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;
}

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

@ -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 <string.h> /* 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)) {
/* <file>/index.d */
strncpy(buf, name, sizeof(buf) - 9);
strncat(buf, separator, 1lu);
strncat(buf, htmlDesc, 7lu);
strncat(buf, html_desc, 7lu);
} else {
/* <file>.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 <file>.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);