Start coding feature allowing "INCLUDE /directory" which basically

includes "/directory/*.rem" files in glob-order.
This commit is contained in:
David F. Skoll
2008-03-22 23:28:51 -04:00
parent af81bbb299
commit 8249964380
5 changed files with 125 additions and 9 deletions

6
configure vendored
View File

@@ -4690,7 +4690,8 @@ _ACEOF
for ac_header in sys/file.h
for ac_header in sys/file.h glob.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -5189,7 +5190,8 @@ fi
for ac_func in setenv unsetenv
for ac_func in setenv unsetenv glob
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ echo "$as_me:$LINENO: checking for $ac_func" >&5

View File

@@ -31,7 +31,7 @@ AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
dnl Checks for header files.
AC_CHECK_HEADERS(sys/file.h)
AC_CHECK_HEADERS(sys/file.h glob.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_STRUCT_TM
@@ -44,7 +44,7 @@ if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wstrict-prototypes"
fi
AC_CHECK_FUNCS(setenv unsetenv)
AC_CHECK_FUNCS(setenv unsetenv glob)
VERSION=03.01.04
AC_SUBST(VERSION)
AC_OUTPUT(src/Makefile www/Makefile src/version.h)

View File

@@ -10,6 +10,11 @@
/* Define if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
/* Define if you have the <glob.h> header file */
#undef HAVE_GLOB_H
#undef HAVE_GLOB
#undef HAVE_SETENV
#undef HAVE_UNSETENV

View File

@@ -30,6 +30,10 @@
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_GLOB_H
#include <glob.h>
#endif
#include "types.h"
#include "protos.h"
#include "globals.h"
@@ -53,9 +57,16 @@ typedef struct cheader {
int ownedByMe;
} CachedFile;
/* A linked list of filenames if we INCLUDE /some/directory/ */
typedef struct fname_chain {
struct fname_chain *next;
char const *filename;
} FilenameChain;
/* Define the structures needed by the INCLUDE file system */
typedef struct {
char const *filename;
FilenameChain *chain;
int LineNo;
unsigned int IfFlags;
int NumIfs;
@@ -76,6 +87,7 @@ static int ReadLineFromFile (void);
static int CacheFile (char const *fname);
static void DestroyCache (CachedFile *cf);
static int CheckSafety (void);
static int PopFile (void);
/***************************************************************/
/* */
@@ -311,13 +323,35 @@ static int CacheFile(char const *fname)
return OK;
}
/***************************************************************/
/* */
/* NextChainedFile - move to the next chained file in a glob */
/* list. */
/* */
/***************************************************************/
static int NextChainedFile(IncludeStruct *i)
{
while(i->chain) {
FilenameChain *cur = i->chain;
i->chain = i->chain->next;
if (OpenFile(cur->filename) == OK) {
free((void *) cur->filename);
free(cur);
return OK;
}
free((void *) cur->filename);
free(cur);
}
return E_EOF;
}
/***************************************************************/
/* */
/* PopFile - we've reached the end. Pop up to the previous */
/* file, or return E_EOF */
/* */
/***************************************************************/
int PopFile(void)
static int PopFile(void)
{
IncludeStruct *i;
@@ -326,8 +360,17 @@ int PopFile(void)
if (!Hush && NumIfs) Eprint("%s", ErrMsg[E_MISS_ENDIF]);
if (!IStackPtr) return E_EOF;
i = &IStack[IStackPtr-1];
if (i->chain) {
int oldRunDisabled = RunDisabled;
if (NextChainedFile(i) == OK) {
return OK;
}
RunDisabled = oldRunDisabled;
}
IStackPtr--;
i = &IStack[IStackPtr];
LineNo = i->LineNo;
IfFlags = i->IfFlags;
@@ -361,13 +404,13 @@ int PopFile(void)
/* */
/***************************************************************/
int DoInclude(ParsePtr p)
{
{
DynamicBuffer buf;
int r, e;
DBufInit(&buf);
if ( (r=ParseToken(p, &buf)) ) return r;
e = VerifyEoln(p);
e = VerifyEoln(p);
if (e) Eprint("%s", ErrMsg[e]);
if ( (r=IncludeFile(DBufValue(&buf))) ) {
DBufFree(&buf);
@@ -379,6 +422,39 @@ int DoInclude(ParsePtr p)
return OK;
}
#ifdef HAVE_GLOB
static int SetupGlobChain(char const *dirname, IncludeStruct *i)
{
DynamicBuffer pattern;
if (!*dirname) return E_CANT_OPEN;
char *dir = StrDup(dirname);
size_t l;
if (!dir) return E_NO_MEM;
/* Strip trailing slashes off directory */
l = strlen(dir);
while(l) {
if (*(dir+l-1) == '/') {
l--;
*(dir+l) = 0;
}
}
/* Repair root directory :-) */
if (!l) {
*dir = '/';
}
DBufInit(&pattern);
DBufPuts(&pattern, dir);
DBufPuts(&pattern, "/*.rem");
return 0;
}
#endif
/***************************************************************/
/* */
/* IncludeFile */
@@ -392,6 +468,7 @@ int IncludeFile(char const *fname)
IncludeStruct *i;
int r;
int oldRunDisabled;
struct stat statbuf;
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
i = &IStack[IStackPtr];
@@ -403,6 +480,7 @@ int IncludeFile(char const *fname)
i->IfFlags = IfFlags;
i->CLine = CLine;
i->offset = -1L;
i->chain = NULL;
if (RunDisabled & RUN_NOTOWNER) {
i->ownedByMe = 0;
} else {
@@ -415,6 +493,38 @@ int IncludeFile(char const *fname)
IStackPtr++;
#ifdef HAVE_GLOB
/* If it's a directory, set up the glob chain here. */
if (stat(fname, &statbuf) == 0) {
FilenameChain *fc;
if (S_ISDIR(statbuf.st_mode)) {
if (SetupGlobChain(fname, i) == OK) { /* Glob succeeded */
if (!i->chain) { /* Oops... no matching files */
return PopFile();
}
while(i->chain) {
fc = i->chain;
i->chain = i->chain->next;
/* Munch first file */
oldRunDisabled = RunDisabled;
if (!OpenFile(fc->filename)) {
free((void *) fc->filename);
free(fc);
return OK;
}
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], fc->filename);
free((void *) fc->filename);
free(fc);
RunDisabled = oldRunDisabled;
}
/* Couldn't open anything... bail */
return PopFile();
}
}
}
#endif
oldRunDisabled = RunDisabled;
/* Try to open the new file */
if (!OpenFile(fname)) {

View File

@@ -37,7 +37,6 @@ void PrintValue (Value *v, FILE *fp);
int CopyValue (Value *dest, const Value *src);
int ReadLine (void);
int OpenFile (char const *fname);
int PopFile (void);
int DoInclude (ParsePtr p);
int IncludeFile (char const *fname);
int GetAccessDate (char const *file);