mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 06:48:47 +02:00
Start coding feature allowing "INCLUDE /directory" which basically
includes "/directory/*.rem" files in glob-order.
This commit is contained in:
6
configure
vendored
6
configure
vendored
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
118
src/files.c
118
src/files.c
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user