📄 wrhash.c
字号:
return( FALSE );
}
return( TRUE );
}
static BOOL WRDiscardChangesQuery( void )
{
char *title;
char *msg;
int ret;
title = WRAllocRCString( WR_EDITSYMBOLSTITLE );
msg = WRAllocRCString( WR_DISCARDCHANGESMSG );
ret = MessageBox( (HWND)NULL, msg, title,
MB_ICONEXCLAMATION | MB_YESNO | MB_TASKMODAL );
if( msg ) {
WRFreeRCString( msg );
}
if( title ) {
WRFreeRCString( title );
}
return( ret == IDYES );
}
static BOOL WRAddUniqueQuery( void )
{
char *title;
char *msg;
int ret;
title = WRAllocRCString( WR_ADDSYMBOLTITLE );
msg = WRAllocRCString( WR_QUERYUNIQUEMSG );
ret = MessageBox( (HWND)NULL, msg, title,
MB_ICONEXCLAMATION | MB_YESNO | MB_TASKMODAL );
if( msg ) {
WRFreeRCString( msg );
}
if( title ) {
WRFreeRCString( title );
}
return( ret == IDYES );
}
static BOOL WRForceAddQuery( void )
{
char *title;
char *msg;
int ret;
title = WRAllocRCString( WR_ADDSYMBOLTITLE );
msg = WRAllocRCString( WR_FORCEADDQUERYMSG );
ret = MessageBox( (HWND)NULL, msg, title,
MB_ICONEXCLAMATION | MB_YESNO | MB_TASKMODAL );
if( msg ) {
WRFreeRCString( msg );
}
if( title ) {
WRFreeRCString( title );
}
return( ret == IDYES );
}
BOOL WR_EXPORT WRFindUnusedHashValue( WRHashTable *table, WRHashValue *value,
WRHashValue start )
{
WRHashValue val;
BOOL found;
if( !table || !value ) {
return( FALSE );
}
found = TRUE;
val = start;
while( WRValueExists( table, val ) ) {
val++;
if( val == 0xffff ) {
if( start < FIRST_DEFAULT_ID ) {
val = 0;
} else {
val = FIRST_DEFAULT_ID;
}
}
if( val == start ) {
found = FALSE;
break;
}
}
if( found ) {
*value = val;
}
return( found );
}
WRHashEntry * WR_EXPORT WRAddDefHashEntry( WRHashTable *table, char *name,
BOOL *dup )
{
WRHashEntry *entry;
WRHashValue value;
if( !table || !name ) {
return( NULL );
}
entry = WRFindHashEntryFromName( table, name );
if( entry ) {
if( dup ) {
*dup = TRUE;
}
return( entry );
}
if( !WRFindUnusedHashValue( table, &value, table->next_default_value ) ) {
return( NULL );
}
entry = WRAddHashEntry( table, name, value, dup, FALSE, TRUE );
if( entry ) {
table->next_default_value = value++;
}
return( entry );
}
WRHashEntry * WR_EXPORT WRAddHashEntry( WRHashTable *table, char *name,
WRHashValue value, BOOL *dup,
BOOL check_unique, BOOL query_force )
{
WRHashEntry *entry;
unsigned int nhash;
unsigned int vhash;
unsigned int size;
char *symbol;
if( !table || !name ) {
return( NULL );
}
symbol = WRStrDup( name );
if( symbol == NULL ) {
return( NULL );
}
WRStripSymbol( symbol );
if( !WRIsValidSymbol( symbol ) ) {
WRMemFree( symbol );
return( NULL );
}
// we do not allow the modification of standard entries
entry = WRFindHashEntryFromName( table, symbol );
if( entry ) {
if( entry->flags & WR_HASHENTRY_STANDARD ) {
return( NULL );
}
}
if( WRValueExists( table, value ) && check_unique ) {
if( !WRAddUniqueQuery() ) {
return( NULL );
}
}
if( entry ) {
if( !*dup && query_force ) {
*dup = WRForceAddQuery();
}
// If dup is TRUE force the add
if( *dup ) {
if( !WRRemoveName( table, symbol ) ) {
return( NULL );
}
}
*dup = TRUE;
} else {
*dup = FALSE;
}
size = sizeof( WRHashEntry ) + strlen( symbol );
entry = (WRHashEntry *)WRMemAlloc( size );
if( entry != NULL ) {
nhash = WRGetNameHash( symbol );
vhash = WRGetValueHash( value );
entry->name_prev = NULL;
entry->value_prev = NULL;
if( table->names[ nhash ] ) {
table->names[ nhash ]->name_prev = entry;
}
if( table->values[ vhash ] ) {
table->values[ vhash ]->value_prev = entry;
}
entry->name_next = table->names[ nhash ];
entry->value_next = table->values[ vhash ];
table->names[ nhash ] = entry;
table->values[ vhash ] = entry;
strcpy( entry->name, symbol );
strupr( entry->name );
entry->value = value;
entry->ref_count = 0;
entry->flags = WR_HASHENTRY_UNUSED;
table->count++;
table->flags |= WR_HASH_DIRTY;
}
WRMemFree( symbol );
return( entry );
}
BOOL WR_EXPORT WRRemoveName( WRHashTable *table, char *name )
{
WRHashEntry *entry;
unsigned int nhash;
unsigned int vhash;
entry = WRFindHashEntryFromName( table, name );
if( ( entry == NULL ) || ( entry->flags & WR_HASHENTRY_STANDARD ) ) {
return( FALSE );
}
nhash = WRGetNameHash( name );
vhash = WRGetValueHash( entry->value );
if( table->names[nhash] == entry ) {
table->names[nhash] = entry->name_next;
}
if( table->values[vhash] == entry ) {
table->values[vhash] = entry->value_next;
}
if( entry->name_next ) {
entry->name_next->name_prev = entry->name_prev;
}
if( entry->name_prev ) {
entry->name_prev->name_next = entry->name_next;
}
if( entry->value_next ) {
entry->value_next->value_prev = entry->value_prev;
}
if( entry->value_prev ) {
entry->value_prev->value_next = entry->value_next;
}
table->count--;
table->flags |= WR_HASH_DIRTY;
WRMemFree( entry );
return( TRUE );
}
void WR_EXPORT WRHashIncRefCount( WRHashEntry *entry )
{
if( entry != NULL ) {
entry->ref_count++;
if( !( entry->flags & WR_HASHENTRY_STANDARD ) ) {
entry->flags &= ~WR_HASHENTRY_UNUSED;
}
}
}
void WR_EXPORT WRHashDecRefCount( WRHashEntry *entry )
{
if( entry != NULL ) {
if( entry->ref_count ) {
entry->ref_count--;
if( !( entry->flags & WR_HASHENTRY_STANDARD ) ) {
if( !entry->ref_count ) {
entry->flags |= WR_HASHENTRY_UNUSED;
}
}
}
}
}
BOOL WR_EXPORT WRLookupName( WRHashTable *table, char *name, WRHashValue *value )
{
WRHashEntry *entry;
entry = WRFindHashEntryFromName( table, name );
if( entry != NULL ) {
if( value != NULL ) {
*value = entry->value;
}
return( TRUE );
}
return( FALSE );
}
int WR_EXPORT WRModifyName( WRHashTable *table, char *name, WRHashValue value, BOOL check_unique )
{
WRHashEntry *entry;
BOOL dup;
// Set dup to cause a force if the symbol exists
dup = TRUE;
entry = WRAddHashEntry( table, name, value, &dup, check_unique, FALSE );
if( entry ) {
table->flags |= WR_HASH_DIRTY;
return( TRUE );
}
return( FALSE );
}
char * WR_EXPORT WRResolveValue( WRHashTable *table, WRHashValue value )
{
char *name;
WRHashValueList *vlist;
name = NULL;
vlist = WRLookupValue( table, value );
if( vlist ) {
if( vlist->next == NULL ) {
name = WRStrDup( vlist->entry->name );
}
WRValueListFree( vlist );
}
return( name );
}
static BOOL WRValueListInsert( WRHashValueList **list, WRHashEntry *entry )
{
WRHashValueList *new;
if( !list || !entry ) {
return( FALSE );
}
new = WRMemAlloc( sizeof( WRHashValueList ) );
if( new == NULL ) {
return( FALSE );
}
new->entry = entry;
new->next = *list;
*list = new;
return( TRUE );
}
void WR_EXPORT WRValueListFree( WRHashValueList *list )
{
WRHashValueList *next;
while( list != NULL ) {
next = list->next;
WRMemFree( list );
list = next;
}
}
WRHashValueList * WR_EXPORT WRLookupValue( WRHashTable *table, WRHashValue value )
{
WRHashValueList *list;
WRHashEntry *entry;
unsigned int hash;
if( table == NULL ) {
return( NULL );
}
list = NULL;
hash = WRGetValueHash( value );
for( entry = table->values[ hash ]; entry; entry = entry->value_next ) {
if( entry->value == value ) {
if( !WRValueListInsert( &list, entry ) ) {
WRValueListFree( list );
return( NULL );
}
}
}
return( list );
}
int WR_EXPORT WRValueExists( WRHashTable *table, WRHashValue value )
{
WRHashEntry *entry;
unsigned int hash;
int count;
if( table == NULL ) {
return( FALSE );
}
count = 0;
hash = WRGetValueHash( value );
for( entry = table->values[ hash ]; entry; entry = entry->value_next ) {
if( entry->value == value ) {
count++;
}
}
return( count );
}
void WR_EXPORT WRStripSymbol( char *symbol )
{
WRStripStr( symbol );
}
BOOL WR_EXPORT WRIsValidSymbol( char *symbol )
{
if( !symbol ) {
return( FALSE );
}
// the following code was not mbcs'ized as WR does not allow
// non-ansi characters in symbol identifiers
if( !isalpha( *symbol ) && ( *symbol != '_' ) ) {
return( FALSE );
}
for( ; *symbol; symbol++ ) {
if( !isalnum( *symbol ) && ( *symbol != '_' ) ) {
return( FALSE );
}
}
return( TRUE );
}
BOOL WR_EXPORT WREditSym( HWND parent, WRHashTable **table,
WRHashEntryFlags *flags, FARPROC help_callback )
{
WREditSymInfo info;
WRHashTable *tmp;
HINSTANCE inst;
FARPROC proc;
int ret;
BOOL ok;
tmp = NULL;
ok = ( table && *table && flags );
if( ok ) {
ok = WRCopyHashTable( &tmp, *table );
}
if( ok ) {
inst = WRGetInstance();
proc = MakeProcInstance( (FARPROC)WREditSymbolsProc, inst );
ok = ( proc != NULL );
}
if( ok ) {
info.hcb = help_callback;
info.table = tmp;
info.modified = FALSE;
info.flags = *flags;
ret = JDialogBoxParam( inst, "WRSymbols", parent, (DLGPROC)proc,
(LPARAM)&info );
FreeProcInstance( proc );
ok = FALSE;
if( ret ) {
UpdateWindow( parent );
if( info.modified ) {
ok = WRCopyHashTable( table, tmp );
}
}
}
if( ok ) {
*flags = info.flags;
}
if( tmp ) {
WRFreeHashTable( tmp );
}
return( ok );
}
static BOOL WRShowSelectedSymbol( HWND hDlg, WRHashTable *table )
{
HWND lbox;
LRESULT index;
WRHashEntry *entry;
BOOL standard_entry;
BOOL ok;
_wtouch(table);
standard_entry = FALSE;
lbox = GetDlgItem( hDlg, IDB_SYM_LISTBOX );
index = SendMessage( lbox, LB_GETCOUNT, 0, 0 );
ok = ( index != LB_ERR );
if( ok ) {
WRSetEditWithULONG( (unsigned long)index, 10, hDlg, IDB_SYM_NUM );
ok = ( index != 0 );
}
if( ok ) {
index = SendMessage( lbox, LB_GETCURSEL, 0, 0 );
entry = (WRHashEntry *)SendMessage( lbox, LB_GETITEMDATA, (WPARAM)index, 0 );
ok = ( entry != NULL );
}
if( ok ) {
standard_entry = ( ( entry->flags & WR_HASHENTRY_STANDARD ) != 0 );
}
EnableWindow( GetDlgItem( hDlg, IDB_SYM_MODIFY ), !standard_entry );
EnableWindow( GetDlgItem( hDlg, IDB_SYM_REMOVE ), !standard_entry );
return( ok );
}
static BOOL WRAddSymbol( HWND hDlg, WRHashTable *table, BOOL force,
char *symbol, WRHashValue value )
{
LRESULT index;
WRHashEntry *entry;
BOOL dup;
BOOL ok;
dup = force;
ok = ( symbol && !WRIsStrSpace( symbol ) );
if( ok ) {
WRStripSymbol( symbol );
ok = WRIsValidSymbol( symbol );
if( !ok ) {
WRDisplayErrorMsg( WR_BADSYMBOL );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -