lang.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 238 行
C
238 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Processing of .dat files used for syntax highlighting.
*
****************************************************************************/
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include "vi.h"
#include "sstyle.h"
#include "lang.h"
static lang_info langInfo[ LANG_MAX ] = {
//table, entries , ref_count ,read_buf
{ NULL, 0, 0, NULL }, // C 1
{ NULL, 0, 0, NULL }, // C++ 2
{ NULL, 0, 0, NULL }, // Fortran 3
{ NULL, 0, 0, NULL }, // Java 4
{ NULL, 0, 0, NULL }, // SQL 5
{ NULL, 0, 0, NULL }, // BAT 6
{ NULL, 0, 0, NULL }, // Basic 7
{ NULL, 0, 0, NULL }, // Perl 8
{ NULL, 0, 0, NULL }, // HTML 9
{ NULL, 0, 0, NULL }, // WML 10
{ NULL, 0, 0, NULL }, // GML 11
{ NULL, 0, 0, NULL }, // DBTest 12
{ NULL, 0, 0, NULL }, // Makefile 13
{ NULL, 0, 0, NULL } // user-defined 14
};
/*
* hashpjw - taken from red dragon book, pg 436
*/
int hashpjw( char *s )
{
unsigned long h = 0, g;
while( *s != '\0' ) {
h = (h << 4) + toupper(*s);
if( g = h & 0xf0000000 ) {
h = h ^ (g >> 24);
h = h ^ g;
}
s++;
}
return( h % langInfo[ CurrentInfo->Language ].table_entries );
}
bool IsKeyword( char *keyword, bool case_ignore )
{
hash_entry *entry;
assert( langInfo[ CurrentInfo->Language ].ref_count > 0 );
entry = langInfo[ CurrentInfo->Language ].keyword_table +
hashpjw( keyword );
if( entry->real == FALSE ) {
return( FALSE );
}
if( case_ignore ) {
while( entry != NULL && stricmp( entry->keyword, keyword ) != 0 ) {
entry = entry->next;
if( entry ) {
assert( entry->real == FALSE );
}
}
} else {
while( entry != NULL && strcmp( entry->keyword, keyword ) != 0 ) {
entry = entry->next;
if( entry ) {
assert( entry->real == FALSE );
}
}
}
return( entry != NULL );
}
hash_entry *createTable( int entries )
{
hash_entry *table;
table = MemAlloc( entries * sizeof( hash_entry ) );
memset( table, 0, entries * sizeof( hash_entry ) );
return( table );
}
char *nextKeyword( char *keyword )
{
while( *keyword ) {
keyword++;
}
return( keyword + 1 );
}
void addTable( hash_entry *table, char *Keyword, int NumKeyword )
{
int i;
hash_entry *entry, *empty;
char *keyword;
typedef struct tagTmpValue {
int hashValue;
char *keyword;
} TmpValue;
TmpValue *tmpValue, *tmpIndex;
tmpValue = tmpIndex = MemAlloc( NumKeyword * sizeof( TmpValue ) );
keyword = Keyword;
for( i = 0; i < NumKeyword; i++ ) {
tmpIndex->hashValue = hashpjw( keyword );
tmpIndex->keyword = keyword;
table[ tmpIndex->hashValue ].real = TRUE;
keyword = nextKeyword( keyword );
tmpIndex++;
}
empty = table;
tmpIndex = tmpValue;
for( i = 0; i < NumKeyword; i++ ) {
assert( table[ tmpIndex->hashValue ].real == TRUE );
entry = table + tmpIndex->hashValue;
if( entry->keyword != NULL ) {
while( entry->next != NULL ) {
entry = entry->next;
}
while( empty->real == TRUE ) {
empty++;
}
entry->next = empty;
entry = empty;
empty++;
}
entry->keyword = tmpIndex->keyword;
entry->next = NULL;
tmpIndex++;
}
MemFree( tmpValue );
}
/*
* LangInit - build hash table based on current language
*/
void LangInit( int newLanguage )
{
int *dummy;
int rc, nkeywords;
char *buff;
char *fname[] = { NULL, "c.dat", "cpp.dat", "fortran.dat", "java.dat", "sql.dat",
"bat.dat", "basic.dat", "perl.dat", "html.dat", "wml.dat",
"gml.dat", "dbtest.dat", "mif.dat", "user.dat" };
assert( CurrentInfo != NULL );
CurrentInfo->Language = newLanguage;
if( newLanguage == LANG_NONE ) {
return;
}
if( langInfo[ newLanguage ].ref_count == 0 ) {
rc = ReadDataFile( fname[ newLanguage ], &nkeywords,
&buff, &dummy, FALSE );
if( rc ) {
Error( GetErrorMsg( rc ) );
CurrentInfo->Language = LANG_NONE;
return;
}
// build new langInfo entry
langInfo[ newLanguage ].table_entries = nkeywords;
langInfo[ newLanguage ].keyword_table =
createTable( NextBiggestPrime( nkeywords ) );
addTable( langInfo[ newLanguage ].keyword_table, buff, nkeywords );
langInfo[ newLanguage ].read_buf = buff;
MemFree( dummy );
}
langInfo[ newLanguage ].ref_count++;
return;
}
/*
* LangFini
*/
void LangFini( int language )
{
if( language == LANG_NONE || langInfo[ language ].ref_count == 0 ) {
return;
}
langInfo[ language ].ref_count--;
if( langInfo[ language ].ref_count == 0 ) {
MemFree( langInfo[ language ].keyword_table );
MemFree( langInfo[ language ].read_buf );
langInfo[ language ].keyword_table = NULL;
langInfo[ language ].table_entries = 0;
}
}
/*
* LangFiniAll
*/
void LangFiniAll( void )
{
int i;
for( i = LANG_NONE; i < LANG_MAX; i++ ) {
while( langInfo[ i ].ref_count ) {
LangFini( i );
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?