Keep a hash table of filenames we've seen so we don't need to strdup the current filename all over the place.

This commit is contained in:
Dianne Skoll
2025-05-24 22:51:16 -04:00
parent a6ca571fe5
commit 8d88192483
12 changed files with 115 additions and 153 deletions

View File

@@ -55,7 +55,7 @@ typedef struct cal_entry {
DynamicBuffer tags;
char passthru[PASSTHRU_LEN+1];
int duration;
char *filename;
char const *filename;
int lineno;
int lineno_start;
Trigger trig;
@@ -1539,7 +1539,6 @@ static int WriteOneColLine(int col)
CalColumn[col] = e->next;
free(e->text);
free(e->raw_text);
free(e->filename);
if (e->wc_text) free(e->wc_text);
FreeTrigInfoChain(e->infos);
free(e);
@@ -1626,7 +1625,6 @@ static int WriteOneColLine(int col)
CalColumn[col] = e->next;
free(e->text);
free(e->raw_text);
free(e->filename);
if (e->wc_text) free(e->wc_text);
FreeTrigInfoChain(e->infos);
free(e);
@@ -2317,17 +2315,7 @@ static int DoCalRem(ParsePtr p, int col)
FreeTrig(&trig);
e->duration = tim.duration;
e->priority = trig.priority;
e->filename = StrDup(FileName);
if(!e->filename) {
FreeTrigInfoChain(e->infos);
if (e->text) free(e->text);
if (e->raw_text) free(e->raw_text);
#ifdef REM_USE_WCHAR
if (e->wc_text) free(e->wc_text);
#endif
free(e);
return E_NO_MEM;
}
e->filename = GetCurrentFilename();
e->lineno = LineNo;
e->lineno_start = LineNoStart;
@@ -2673,7 +2661,6 @@ static void WriteSimpleEntries(int col, int dse)
free(e->text);
free(e->raw_text);
free(e->filename);
FreeTrigInfoChain(e->infos);
#ifdef REM_USE_WCHAR
if (e->wc_text) free(e->wc_text);

View File

@@ -1572,7 +1572,7 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
int y, m, d;
FromDSE(LastTriggerDate, &y, &m, &d);
fprintf(ErrFp, "%s(%s): Trig(satisfied) = %s, %d %s, %d",
FileName, line_range(LineNoStart, LineNo),
GetCurrentFilename(), line_range(LineNoStart, LineNo),
get_day_name(LastTriggerDate % 7),
d,
get_month_name(m),

View File

@@ -20,6 +20,7 @@
#include <errno.h>
#include <ctype.h>
#include <sys/stat.h>
#include <stddef.h>
#ifdef TM_IN_SYS_TIME
#include <sys/time.h>
@@ -85,10 +86,21 @@ typedef struct {
int ownedByMe;
} IncludeStruct;
typedef struct fn_entry {
struct hash_link link;
char const *fname;
} FilenameHashEntry;
/* A hash table to hold unique copies of all the filenames we process */
static hash_table FilenameHashTable;
static CachedFile *CachedFiles = (CachedFile *) NULL;
static CachedLine *CLine = (CachedLine *) NULL;
static DirectoryFilenameChain *CachedDirectoryChains = NULL;
/* Current filename */
static char const *FileName = NULL;
static FILE *fp;
static IncludeStruct IStack[INCLUDE_NEST];
@@ -102,6 +114,60 @@ static int CheckSafetyAux (struct stat *statbuf);
static int PopFile (void);
static int IncludeCmd(char const *);
static unsigned int FnHashFunc(void *x)
{
FilenameHashEntry *e = (FilenameHashEntry *) x;
return HashVal_preservecase(e->fname);
}
static int FnCompareFunc(void *a, void *b)
{
FilenameHashEntry *e1 = (FilenameHashEntry *) a;
FilenameHashEntry *e2 = (FilenameHashEntry *) b;
return strcmp(e1->fname, e2->fname);
}
void InitFiles(void)
{
if (hash_table_init(&FilenameHashTable, offsetof(FilenameHashEntry, link),
FnHashFunc, FnCompareFunc) < 0) {
fprintf(ErrFp, "Unable to initialize filename hash table: Out of memory. Exiting.\n");
exit(1);
}
}
void SetCurrentFilename(char const *fname)
{
FilenameHashEntry *e;
FilenameHashEntry candidate;
candidate.fname = fname;
e = (FilenameHashEntry *) hash_table_find(&FilenameHashTable, &candidate);
if (!e) {
e = NEW(FilenameHashEntry);
if (!e) {
fprintf(ErrFp, "Out of Memory!\n");
exit(1);
}
e->fname = strdup(fname);
if (!e->fname) {
fprintf(ErrFp, "Out of Memory!\n");
exit(1);
}
hash_table_insert(&FilenameHashTable, e);
}
FileName = e->fname;
}
char const *GetCurrentFilename(void)
{
if (FileName) {
return FileName;
} else {
return "";
}
}
static void
got_a_fresh_line(void)
{
@@ -332,7 +398,7 @@ int OpenFile(char const *fname)
fprintf(ErrFp, "\n");
}
CLine = h->cache;
STRSET(FileName, fname);
SetCurrentFilename(fname);
LineNo = 0;
LineNoStart = 0;
if (!h->ownedByMe) {
@@ -387,7 +453,7 @@ int OpenFile(char const *fname)
}
}
}
STRSET(FileName, fname);
SetCurrentFilename(fname);
LineNo = 0;
LineNoStart = 0;
if (FileName) return OK; else return E_NO_MEM;
@@ -569,7 +635,7 @@ static int PopFile(void)
set_base_if_pointer(i->base_if_pointer);
CLine = i->CLine;
fp = NULL;
STRSET(FileName, i->filename);
SetCurrentFilename(i->filename);
if (!i->ownedByMe) {
RunDisabled |= RUN_NOTOWNER;
} else {
@@ -589,7 +655,6 @@ static int PopFile(void)
if (fp != stdin)
(void) fseek(fp, i->offset, 0); /* Trust that it works... */
}
free((char *) i->filename);
return OK;
}
@@ -894,15 +959,7 @@ static int IncludeCmd(char const *cmd)
}
fname = DBufValue(&buf);
if (FileName) {
i->filename = StrDup(FileName);
if (!i->filename) {
DBufFree(&buf);
return E_NO_MEM;
}
} else {
i->filename = NULL;
}
i->filename = FileName;
i->ownedByMe = 1;
i->LineNo = LineNo;
i->LineNoStart = LineNo;
@@ -927,7 +984,7 @@ static int IncludeCmd(char const *cmd)
fprintf(ErrFp, "\n");
}
CLine = h->cache;
STRSET(FileName, fname);
SetCurrentFilename(fname);
DBufFree(&buf);
LineNo = 0;
LineNoStart = 0;
@@ -979,7 +1036,7 @@ static int IncludeCmd(char const *cmd)
CLine = CachedFiles->cache;
LineNo = 0;
LineNoStart = 0;
STRSET(FileName, fname);
SetCurrentFilename(fname);
DBufFree(&buf);
return OK;
}
@@ -1008,12 +1065,7 @@ int IncludeFile(char const *fname)
if (IStackPtr >= INCLUDE_NEST) return E_NESTED_INCLUDE;
i = &IStack[IStackPtr];
if (FileName) {
i->filename = StrDup(FileName);
if (!i->filename) return E_NO_MEM;
} else {
i->filename = NULL;
}
i->filename = FileName;
i->LineNo = LineNo;
i->LineNoStart = LineNoStart;
i->base_if_pointer = get_base_if_pointer();

View File

@@ -2287,7 +2287,7 @@ static int FIif(expr_node *node, Value *locals, Value *ans, int *nonconst)
/***************************************************************/
static int FFilename(func_info *info)
{
return RetStrVal(FileName, info);
return RetStrVal(GetCurrentFilename(), info);
}
/***************************************************************/
@@ -2305,7 +2305,7 @@ static int FFiledir(func_info *info)
DBufInit(&buf);
if (DBufPuts(&buf, FileName) != OK) return E_NO_MEM;
if (DBufPuts(&buf, GetCurrentFilename()) != OK) return E_NO_MEM;
if (DBufLen(&buf) == 0) {
DBufFree(&buf);
return RetStrVal(".", info);

View File

@@ -113,7 +113,6 @@ EXTERN INIT( int SynthesizeTags, 0);
EXTERN INIT( int ScFormat, SC_AMPM);
EXTERN INIT( int MaxSatIter, 1000);
EXTERN INIT( int MaxStringLen, MAX_STR_LEN);
EXTERN INIT( char *FileName, NULL);
EXTERN INIT( int UseStdin, 0);
EXTERN INIT( int PurgeMode, 0);
EXTERN INIT( int PurgeIncludeDepth, 0);

View File

@@ -186,6 +186,7 @@ void InitRemind(int argc, char const *argv[])
InitUserFunctions();
InitTranslationTable();
InitFiles();
/* If stdout is a terminal, initialize $FormWidth to terminal width-8,
but clamp to [20, 500] */

View File

@@ -902,17 +902,18 @@ void Wprint(char const *fmt, ...)
{
va_list argptr;
char const *fname = GetCurrentFilename();
if (SuppressErrorOutputInCatch) {
return;
}
/* We can't use line_range because caller might have used it */
if (FileName) {
if (strcmp(FileName, "-")) {
if (fname) {
if (strcmp(fname, "-")) {
if (LineNoStart == LineNo) {
(void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
(void) fprintf(ErrFp, "%s(%d): ", fname, LineNo);
} else {
(void) fprintf(ErrFp, "%s(%d:%d): ", FileName, LineNoStart, LineNo);
(void) fprintf(ErrFp, "%s(%d:%d): ", fname, LineNoStart, LineNo);
}
} else {
if (LineNoStart == LineNo) {
@@ -937,22 +938,24 @@ void Wprint(char const *fmt, ...)
void Eprint(char const *fmt, ...)
{
va_list argptr;
char const *fname;
if (SuppressErrorOutputInCatch) {
return;
}
/* Check if more than one error msg. from this line */
if (!FreshLine && !ShowAllErrors) return;
if (!FileName) {
char const *fname = GetCurrentFilename();
if (!fname) {
return;
}
if (strcmp(FileName, "-")) {
fname = FileName;
} else {
if (LineNo < 1) {
/* Not yet processing a file */
return;
}
/* Check if more than one error msg. from this line */
if (!FreshLine && !ShowAllErrors) return;
if (!strcmp(fname, "-")) {
fname = "-stdin-";
}
if (FreshLine) {

View File

@@ -36,7 +36,7 @@ int NumFullOmits, NumPartialOmits;
/* The structure for saving and restoring OMIT contexts */
typedef struct omitcontext {
struct omitcontext *next;
char *filename;
char const *filename;
int lineno;
int numfull, numpart;
int *fullsave;
@@ -98,7 +98,6 @@ int DestroyOmitContexts(int print_unmatched)
num++;
if (c->fullsave) free(c->fullsave);
if (c->partsave) free(c->partsave);
if (c->filename) free(c->filename);
d = c->next;
free(c);
c = d;
@@ -122,14 +121,10 @@ int PushOmitContext(ParsePtr p)
context = NEW(OmitContext);
if (!context) return E_NO_MEM;
if (FileName) {
context->filename = StrDup(FileName);
if (GetCurrentFilename()) {
context->filename = GetCurrentFilename();
} else {
context->filename = StrDup("");
}
if (!context->filename) {
free(context);
return E_NO_MEM;
context->filename = "";
}
context->lineno = LineNo;
context->numfull = NumFullOmits;
@@ -137,13 +132,11 @@ int PushOmitContext(ParsePtr p)
context->weekdaysave = WeekdayOmits;
context->fullsave = malloc(NumFullOmits * sizeof(int));
if (NumFullOmits && !context->fullsave) {
free(context->filename);
free(context);
return E_NO_MEM;
}
context->partsave = malloc(NumPartialOmits * sizeof(int));
if (NumPartialOmits && !context->partsave) {
free(context->filename);
if (context->fullsave) {
free(context->fullsave);
}
@@ -172,6 +165,7 @@ int PopOmitContext(ParsePtr p)
{
OmitContext *c = SavedOmitContexts;
char const *fname = GetCurrentFilename();
if (!c) return E_POP_NO_PUSH;
NumFullOmits = c->numfull;
@@ -185,13 +179,12 @@ int PopOmitContext(ParsePtr p)
/* Remove the context from the stack */
SavedOmitContexts = c->next;
if (c->filename && FileName && strcmp(c->filename, FileName)) {
Wprint(tr("POP-OMIT-CONTEXT at %s:%d matches PUSH-OMIT-CONTEXT in different file: %s:%d"), FileName, LineNo, c->filename, c->lineno);
if (c->filename && fname && strcmp(c->filename, fname)) {
Wprint(tr("POP-OMIT-CONTEXT at %s:%d matches PUSH-OMIT-CONTEXT in different file: %s:%d"), fname, LineNo, c->filename, c->lineno);
}
/* Free memory used by the saved context */
if (c->partsave) free(c->partsave);
if (c->fullsave) free(c->fullsave);
if (c->filename) free(c->filename);
free(c);
return VerifyEoln(p);

View File

@@ -269,6 +269,7 @@ void InitDedupeTable(void);
void InitVars(void);
void InitUserFunctions(void);
void InitTranslationTable(void);
void InitFiles(void);
char const *GetTranslatedString(char const *orig);
int GetTranslatedStringTryingVariants(char const *orig, DynamicBuffer *out);
char const *GetErr(int r);
@@ -305,8 +306,5 @@ int should_ignore_line(void);
int in_constant_context(void);
void pop_excess_ifs(char const *fname);
void SetCurrentFilename(char const *fname);
char const *GetCurrentFilename(void);

View File

@@ -45,13 +45,6 @@ static void consume_inotify_events(int fd);
static int setup_inotify_watch(void);
#endif
/* A list of filenames associated with queued reminders */
typedef struct queuedfname {
struct queuedfname *next;
char const *fname;
} QueuedFilename;
/* List structure for holding queued reminders */
typedef struct queuedrem {
struct queuedrem *next;
@@ -72,7 +65,6 @@ typedef struct queuedrem {
/* Global variables */
static QueuedRem *QueueHead = NULL;
static QueuedFilename *Files = NULL;
static time_t FileModTime;
static struct stat StatBuf;
@@ -83,7 +75,6 @@ static int CalculateNextTimeUsingSched (QueuedRem *q);
static void ServerWait (struct timeval *sleep_tv);
static void reread (void);
static void PrintQueue(void);
static char const *QueueFilename(char const *fname);
static void chomp(DynamicBuffer *buf)
{
@@ -112,48 +103,6 @@ char const *SimpleTimeNoSpace(int tim)
return s;
}
/***************************************************************/
/* */
/* QueueFilename */
/* */
/* Add fname to the list of queued filenames if it's not */
/* already present. Either way, return a pointer to the */
/* filename. Returns NULL if out of memory */
/* */
/***************************************************************/
static QueuedFilename *last_file_found = NULL;
static char const *QueueFilename(char const *fname)
{
QueuedFilename *elem = Files;
/* Optimization: We are very likely in the same file as
before... */
if (last_file_found && !strcmp(fname, last_file_found->fname)) {
return last_file_found->fname;
}
/* No such luck; search the list */
while(elem) {
if (!strcmp(elem->fname, fname)) {
last_file_found = elem;
return elem->fname;
}
elem = elem->next;
}
/* Not found... queue it */
elem = NEW(QueuedFilename);
if (!elem) return NULL;
elem->fname = StrDup(fname);
if (!elem->fname) {
free(elem);
return NULL;
}
elem->next = Files;
Files = elem;
last_file_found = elem;
return elem->fname;
}
static void del_reminder(QueuedRem *qid)
{
QueuedRem *q = QueueHead;
@@ -217,13 +166,7 @@ int QueueReminder(ParsePtr p, Trigger *trig,
free(qelem);
return E_NO_MEM;
}
qelem->fname = QueueFilename(FileName);
if (!qelem->fname) {
free((void *) qelem->text);
free(qelem);
return E_NO_MEM;
}
qelem->fname = GetCurrentFilename();
qelem->lineno = LineNo;
qelem->lineno_start = LineNoStart;
NumQueued++;
@@ -327,12 +270,6 @@ void HandleQueuedReminders(void)
/* Turn off sorting -- otherwise, TriggerReminder has no effect! */
SortByDate = 0;
/* Free FileName if necessary */
if (FileName) {
free(FileName);
FileName = NULL;
}
/* We don't need to keep the dedupe table around */
ClearDedupeTable();
@@ -495,7 +432,7 @@ void HandleQueuedReminders(void)
/* Set up global variables so some functions like trigdate()
and trigtime() work correctly */
SaveAllTriggerInfo(&(q->t), &(q->tt), DSEToday, q->tt.ttime, 1);
FileName = (char *) q->fname;
SetCurrentFilename(q->fname);
DefaultColorR = q->red;
DefaultColorG = q->green;
DefaultColorB = q->blue;
@@ -516,7 +453,6 @@ void HandleQueuedReminders(void)
} else {
(void) TriggerReminder(&p, &tcopy, &q->tt, DSEToday, 1, NULL);
}
FileName = NULL;
if (IsServerMode() && !DaemonJSON && q->typ != RUN_TYPE) {
printf("NOTE endreminder\n");
}

View File

@@ -453,7 +453,7 @@ AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int sav
if (DebugFlag & DB_PRTTRIG) {
FromDSE(r, &y, &m, &d);
fprintf(ErrFp, "%s(%s): Trig(adj) = %s, %d %s, %d",
FileName, line_range(LineNoStart, LineNo),
GetCurrentFilename(), line_range(LineNoStart, LineNo),
get_day_name(r % 7),
d,
get_month_name(m),
@@ -581,7 +581,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
trig->expired = 1;
if (DebugFlag & DB_PRTTRIG) {
fprintf(ErrFp, "%s(%s): %s\n",
FileName, line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
GetCurrentFilename(), line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
}
return -1;
}
@@ -604,7 +604,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
if (DebugFlag & DB_PRTTRIG) {
FromDSE(result, &y, &m, &d);
fprintf(ErrFp, "%s(%s): Trig = %s, %d %s, %d",
FileName, line_range(LineNoStart, LineNo),
GetCurrentFilename(), line_range(LineNoStart, LineNo),
get_day_name(result % 7),
d,
get_month_name(m),
@@ -631,7 +631,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
trig->expired = 1;
if (DebugFlag & DB_PRTTRIG) {
fprintf(ErrFp, "%s(%s): %s\n",
FileName, line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
GetCurrentFilename(), line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
}
if (save_in_globals) {
LastTriggerDate = result;
@@ -656,7 +656,7 @@ int ComputeTriggerNoAdjustDuration(int today, Trigger *trig, TimeTrig *tim,
trig->expired = 1;
if (DebugFlag & DB_PRTTRIG) {
fprintf(ErrFp, "%s(%s): %s\n",
FileName, line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
GetCurrentFilename(), line_range(LineNoStart, LineNo), GetErr(E_EXPIRED));
}
return -1;
}

View File

@@ -214,7 +214,7 @@ int DoFset(ParsePtr p)
file, do nothing */
existing = FindUserFunc(DBufValue(&buf));
if (existing) {
if (!strcmp(existing->filename, FileName) &&
if (!strcmp(existing->filename, GetCurrentFilename()) &&
strcmp(existing->filename, "[cmdline]") &&
existing->lineno == LineNo) {
DBufFree(&buf);
@@ -242,14 +242,10 @@ int DoFset(ParsePtr p)
DBufFree(&buf);
return E_NO_MEM;
}
if (FileName) {
func->filename = StrDup(FileName);
if (GetCurrentFilename()) {
func->filename = GetCurrentFilename();
} else {
func->filename = StrDup("[cmdline]");
}
if (!func->filename) {
free(func);
return E_NO_MEM;
func->filename = "[cmdline]";
}
func->lineno = LineNo;
func->lineno_start = LineNoStart;
@@ -393,9 +389,6 @@ static void DestroyUserFunc(UserFunc *f)
/* Free the function definition */
if (f->node) free_expr_tree(f->node);
/* Free the filename */
if (f->filename) free( (char *) f->filename);
/* Free arg names */
if (f->args) {
for (i=0; i<f->nargs; i++) {