/* Copyright (C) 2003, 2004 Dave Bayer. Subject to the terms and conditions of the MIT License. */ #include "root.h" #include "file.h" #include "filter.h" #include "rules.h" #include "merge.h" #include "html.h" #include "dict.h" /*. dictFilename */ static char *filename; void dictFilename( char *name ) { filename = name; } /*. dictEntry */ typedef struct dictEntry { char *name, *file; BOOL local; struct dictEntry *next; } dictEntry; /*. dictHashTable */ dictEntry *dictHashTable[PRIME]; /*. dictEntryNew */ static dictEntry *dictEntryNew( char *name, BOOL local ) { dictEntry *entry; unsigned len; entry = malloc( sizeof( *entry )); len = strlen( name ) + 1; entry->name = malloc( len * sizeof( char )); strncpy( entry->name, name, len ); entry->file = filename; entry->local = local; entry->next = 0; return entry; } /*. dictFree */ void dictFree( void ) { int i; dictEntry **pp, *p, *q; for ( i=0, pp=dictHashTable; inext; free( p->name ); free( p ); p = q; } } /*. dictEntryLocate */ static dictEntry **dictEntryLocate( char *name ) { char *s; unsigned temp, hash; dictEntry *entry, **pentry; hash = 0; for ( s=name; *s!=0; ++s ) HASH( temp, hash, *s ); hash %= PRIME; pentry = dictHashTable + hash; while ( ( entry = *pentry ) != 0 ) { if ( strcmp( entry->name, name ) == 0 && ( !entry->local || strcmp( entry->file, filename ) == 0 )) break; pentry = &entry->next; } return pentry; } /*. dictEntryInsert */ static BOOL dictEntryInsert( char *name, BOOL local ) { dictEntry **pentry; pentry = dictEntryLocate( name ); if ( *pentry != 0 ) return NO; *pentry = dictEntryNew( name, local ); return YES; } /*. dictEntryLookup */ static dictEntry *dictEntryLookup( char *name ) { return *dictEntryLocate( name ); } /*. iscsym */ static BOOL iscsym (char c) { return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || (c == '_') || ((c >= '0') && (c <= '9')) ? YES : NO; } /*. iscsymf */ static BOOL iscsymf (char c) { return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || (c == '_') ? YES : NO; } /*. dictDefine */ BOOL dictDefine( line *l, char *buf ) { filterMark *m; char c, *s, *t; BOOL local, ok; m = l->data; assert( m != 0 && ( m->mark == mergeGlobal || m->mark == mergeLocal )); local = m->mark == mergeLocal ? YES : NO; /* find C identifier */ s = l->s + m->index; while ( !iscsymf( *s )) if ( *s++ == '\0' ) return NO; t = s; while ( iscsym( *++t )) {} c = *t; *t = '\0'; sprintf( buf, "

\n%s\n

\n\n", s, s ); ok = dictEntryInsert( s, local ); *t = c; return ok; } /*. dictFilter */ unsigned dictFilter( char **ps, char **pt, unsigned state ) { char c, *s, buf[LEN]; dictEntry *entry; if (( state == dictCode || state == dictSamp || state == dictPre ) && iscsym( **ps )) { s = *ps; while ( iscsym( *++s )) {} c = *s; *s = '\0'; entry = dictEntryLookup( *ps ); if ( entry != 0 ) { if ( entry->file == filename ) sprintf( *pt, "%s", entry->name, entry->name ); else { makeRelativeName( filename, entry->file, buf, LEN ); sprintf( *pt, "%s", buf, entry->name, entry->name ); } } else strcpy( *pt, *ps ); *ps = s; *s = c; *pt += strlen( *pt ); } else *(*pt)++ = *(*ps)++; return state; }