⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hash.c

📁 类PASCAL语言的编译器,LINUX环境的,我没试过是否正确.
💻 C
📖 第 1 页 / 共 3 页
字号:
  ReturnCode ret;  struct Identifier *get;  unsigned long hash=Gethash(name);  get=scr->hash[hash%scr->hash_size];#ifdef DEBUG  hashed=0;#endif  while(get) {    if(       (get->hash==hash) &&        /* identical hash value! */       !strcmp(get->name, name) &&       /* identical name! */       (get->flags&(FPL_GLOBAL_SYMBOL|FPL_EXPORT_SYMBOL) ||        (get->func==scr->func && get->level<=scr->varlevel)) &&       /* If not global, declared under the *same* function, in this or	  a lower level! */       (get->flags&FPL_EXPORT_SYMBOL || !strcmp(get->file, scr->prog->name))       /* If not cross-file, the same file! */       ) {      /* this is it! */      *ident=get;#ifdef DEBUG      if(hashed>max_hashed)	max_hashed=hashed;#endif      if(get->flags&FPL_EXTERNAL_VARIABLE) {        CALL(Hijack(scr, get));      }      else if(scr->flags&FPLDATA_ISOLATE && get->flags&FPL_EXPORT_SYMBOL) {        /*         * Isolated and exported symbol... really?         */        if((get->flags&(FPL_FUNCTION|FPL_KEYWORD) == FPL_INSIDE_FUNCTION) ||           get->flags&FPL_VARIABLE) {          /*           * Nope, this symbol shouldn't get returned!           */          break;        }      }#ifdef DEBUGMAIL      DebugMail(scr, MAIL_IDENTIFIER_ACCESS, 0, get);#endif      return FPL_OK;    } else if(get->hash<hash)      /* we've been searching through all possible alternatives! */      break;#ifdef DEBUG    hashed++;#endif    get=get->next;  }  *ident=NULL;  return FPLERR_IDENTIFIER_NOT_FOUND;}#ifndef AMIGA /* if not using SAS/C on Amiga */#ifdef VARARG_FUNCTIONSlong fplAddVariableTags(void *anchor, uchar *name, long ID, uchar type,                        void *defvalue, ...){  va_list tags;  long ret;#ifdef SUNOS  va_start(tags); /* get parameter list */#else  va_start(tags, defvalue); /* get parameter list */#endif  ret = fplAddVariable(anchor, name, ID, type, defvalue, (unsigned long *)tags);  va_end(tags);  return ret;}#elselong PREFIX fplAddVariableTags(void *anchor, uchar *name, long ID, uchar type,                               void *defvalue, unsigned long tags, ...){  return fplAddVariable(anchor, name, ID, type, defvalue, &tags);}#endif#endif/********************************************************************** * * int fplAddVariable(); * * User frontend to AddIdentifier(). New in version 10! * *****/ReturnCode PREFIX  fplAddVariable(AREG(0) struct Data *scr, /* pointer to struct Data */		 AREG(1) uchar *name,       /* name of variable */		 DREG(0) long ID,	   /* variable ID */		 DREG(1) uchar type,        /* variable type */                 AREG(2) void *defvalue,   /* default value */		 AREG(3) unsigned long *tags) /* taglist pointer */{  ReturnCode ret;  struct Identifier *ident;#ifdef DEBUGMAIL  DebugMail(scr, MAIL_FUNCTION, 500, "fplAddVariable");#endif  if(!scr)    return(FPLERR_ILLEGAL_ANCHOR);  GETMEMA(ident, sizeof(struct Identifier));  memset(&ident->data.variable, 0, sizeof(struct fplVariable));  ident->name = name;  ident->data.variable.ID = ID;  ident->flags = FPL_EXTERNAL_VARIABLE|FPL_GLOBAL_SYMBOL|FPL_EXPORT_SYMBOL|    (type == FPL_STRARG? FPL_STRING_VARIABLE:FPL_INT_VARIABLE)|      FPL_READONLY;  if(type == FPL_INTARG) {    GETMEM(ident->data.variable.var.val32, sizeof(long));    ident->data.variable.var.val32[0] = (long) defvalue;  }  else    if(defvalue) {      register long len = (long)strlen((uchar *)defvalue);      if(len) {        GETMEM(ident->data.variable.var.str, sizeof(struct fplStr *));        GETMEM(ident->data.variable.var.str[0], len + sizeof(struct fplStr));        ident->data.variable.var.str[0]->len = len;        ident->data.variable.var.str[0]->alloc = len;        memcpy(ident->data.variable.var.str[0]->string, defvalue,               len);        ident->data.variable.var.str[0]->string[len] = '\0'; /* Z-terminate */      }    }  ident->file = "<user>"; /* Used added! */  ident->func = NULL; /* everywhere! */  ident->level = 0;  CALL(AddIdentifier(scr, ident));  return(FPL_OK);}/************************************************************************* * * Hijack(); * * This function gets called whenever an external variable has been selected * by GetIdentifier(). * ******/static ReturnCode INLINE Hijack(struct Data *scr, struct Identifier *ident){  struct fplArgument pass;  struct fplMsg *msg;  ReturnCode ret;  memset(&pass, 0, sizeof(struct fplArgument));  pass.argc=0;  pass.name=ident->name;  pass.ID=ident->data.variable.ID;  pass.key=scr;  pass.variable = (void *)    (ident->flags&FPL_STRING_VARIABLE?     (ident->data.variable.var.str &&ident->data.variable.var.str[0]?      ident->data.variable.var.str[0]->string:""):     (void *)ident->data.variable.var.val32[0]);  CALL(InterfaceCall(scr, &pass, scr->function));  if(ident->flags&FPL_INT_VARIABLE) {    /*     * Integer variable!     */    CALL(GetMessage(scr, FPLMSG_RETURN, &msg));    if(msg && msg->flags&FPLMSG_FLG_INT) {      ident->data.variable.var.val32[0]=(long)msg->message[0];      CALL(DeleteMessage(scr, msg));    }  } else {    /*     * String variable!     */    CALL(GetMessage(scr, FPLMSG_RETURN, &msg));    if(msg && msg->flags&FPLMSG_FLG_STRING) {      if(!ident->data.variable.var.str) {	GETMEMA(ident->data.variable.var.str, sizeof(struct fplStr *));      }      else if(ident->data.variable.var.str[0]) {	FREEA(ident->data.variable.var.str[0]);      }      ident->data.variable.var.str[0]=(struct fplStr *)msg->message[0];      /*       * Make the string to be static always!       */      SwapMem(scr, ident->data.variable.var.str[0], MALLOC_STATIC);      DeleteMessage(scr, msg);    }  }  return(FPL_OK);}/********************************************************************** * * int InitHash() * * Initialize the hash table. Simple and quick! * *****/struct ShitData {  uchar *name;  long ID;  uchar ret;  uchar *format;};struct MoreShitData {  uchar *name;  long ID;  long flags;};static ReturnCode INLINE InitHash(struct Data *scr){  ReturnCode ret;  static struct ShitData internal_functions[]={    {"abs",		FNC_ABS,	'I', "I"},    {"atoi",		FNC_ATOI,	'I', "S"},    {"closelib",	FNC_CLOSELIB,	'I', "S"},  /* amiga only */    {"debug",		FNC_DEBUG,	'I', "i"},    {"eval",		FNC_EVAL,	'I', "S"},    {"exists",          FNC_EXISTS,     'I', "Si"},    {"interpret",	FNC_INTERPRET,	'I', "S"},    {"itoa",		FNC_ITOA,	'S', "I"},    {"itoc",		FNC_ITOC,	'S', "I"},    {"joinstr",		FNC_JOINSTR,	'S', "s>"},    {"ltostr",		FNC_LTOSTR,	'S', "Ii"},    {"openlib",		FNC_OPENLIB,	'I', "SI"}, /* amiga only */    {"rename",		FNC_RENAME,     'I', "SS"},    {"sprintf",		FNC_SPRINTF,	'S', "Sa>"},    {"sscanf",          FNC_SSCANF,     'I', "SSa>"},    {"strcmp",		FNC_STRCMP,	'I', "SS"},    {"stricmp",		FNC_STRICMP,	'I', "SS"},    {"strlen",		FNC_STRLEN,	'I', "S"},    {"strncmp",		FNC_STRNCMP,	'I', "SSI"},    {"strnicmp",	FNC_STRNICMP,	'I', "SSI"},    {"strstr",		FNC_STRSTR,	'I', "SSi"},    {"stristr",		FNC_STRISTR,	'I', "SSi"},    {"strtol",		FNC_STRTOL,	'I', "Si"},    {"substr",		FNC_SUBSTR,	'S', "SII"},  };  /* FPL keywords. "else" is not included (treated special). Is is     defines as KEYWORD_ELSE */  static struct MoreShitData keywords[]={    {"auto",	CMD_AUTO,	FPL_KEYWORD_DECLARE},    {"break",	CMD_BREAK,	0},    {"case",	CMD_CASE,	0},    {"char",	CMD_INT,	FPL_KEYWORD_DECLARE|FPL_CHAR_VARIABLE},    {"const",	CMD_CONST,	FPL_KEYWORD_DECLARE},    {"continue", CMD_CONTINUE,	0},    {"default",	CMD_DEFAULT,	0},    {"do",	CMD_DO,		0},    {"double",	CMD_DOUBLE,	FPL_IGNORE},    {"enum",	CMD_ENUM,	FPL_IGNORE},    {"exit",	CMD_EXIT,	0},    {"export",	CMD_EXPORT,	FPL_KEYWORD_DECLARE},    {"float",   CMD_FLOAT,	FPL_IGNORE},    {"for",	CMD_FOR,	0},    {"if",	CMD_IF,		0},    {"int",	CMD_INT,	FPL_KEYWORD_DECLARE},    {"long",	CMD_INT,	FPL_KEYWORD_DECLARE},    {"register",CMD_REGISTER,	FPL_KEYWORD_DECLARE},    {"resize",	CMD_RESIZE,	0},    {"return",	CMD_RETURN,	0},    {"short",	CMD_INT,	FPL_KEYWORD_DECLARE|FPL_SHORT_VARIABLE},    {"signed",	CMD_SIGNED,	FPL_KEYWORD_DECLARE|FPL_IGNORE},    {"static",  CMD_STATIC,	FPL_KEYWORD_DECLARE},    {"string",	CMD_STRING,	FPL_KEYWORD_DECLARE},    {"struct",  CMD_STRUCT,	FPL_IGNORE},    {"switch",	CMD_SWITCH,	0},    {"typedef",	CMD_TYPEDEF,	0},    {"union",	CMD_UNION,	FPL_IGNORE},    {"unsigned",CMD_UNSIGNED,	FPL_KEYWORD_DECLARE|FPL_IGNORE},    {"void",	CMD_VOID,	FPL_KEYWORD_DECLARE},    {"volatile",CMD_VOLATILE,	FPL_KEYWORD_DECLARE|FPL_IGNORE},    {"while",	CMD_WHILE,	0},  };  long i;  struct Identifier *ident;  GETMEMA(scr->hash, sizeof(struct Identifier *)* scr->hash_size);  memset((void *)scr->hash, 0, sizeof(struct Identifier *)*scr->hash_size);  /*   * The hash table initialization gives us a brilliant chance to bring up   * the execution speed even more by inserting the few internal functions   * into this same table. The functions will then act *EXACTLY* the same   * and we can shorten the code and much easier write internal functions   * that return strings...   */  for(i=0; i<sizeof(internal_functions)/sizeof(struct ShitData);i++) {    GETMEMA(ident, sizeof(struct Identifier));    ident->name=internal_functions[i].name;    ident->data.external.ID=internal_functions[i].ID;    ident->data.external.ret=internal_functions[i].ret;    ident->data.external.format=internal_functions[i].format;    ident->flags=FPL_INTERNAL_FUNCTION|FPL_EXPORT_SYMBOL;    ident->level=0;    ident->func=NULL; /* all functions */    ident->file= "<FPL>"; /* internal */    ret=AddIdentifier(scr, ident);    if(ret)      break;  }  for(i=0; i<sizeof(keywords)/sizeof(struct MoreShitData);i++) {    GETMEMA(ident, sizeof(struct Identifier));    ident->name=keywords[i].name;    ident->data.external.ID=keywords[i].ID;  /* dirty enum work! */    ident->flags=FPL_EXPORT_SYMBOL|FPL_KEYWORD|keywords[i].flags;    ident->level=0;    ident->func=NULL;  /* all functions */    ident->file= "<FPL>";  /* internal */    ret=AddIdentifier(scr, ident);    if(ret)      break;  }  return(ret);}/********************************************************************** * * int Gethash(); * * Return the hash number for the name received as argument. * *****/static unsigned long INLINE Gethash(uchar *name){  unsigned long hash=0;  while(*name)    hash=(hash<<1)+*name+++(hash&(1<<31)?-2000000000:0);  return(hash);}/********************************************************************** * * void Free(); * * This function frees the resources used by this FPL session. * ***********/void PREFIX fplFree(AREG(0) struct Data *scr){  struct Data onstack;#ifdef AMIGA  long retval;#endif#ifdef DEBUGMAIL  DebugMail(scr, MAIL_FUNCTION, 500, "fplFree");#endif  onstack=*scr; /* copy the entire struct */  scr=&onstack; /* use the `stack-struct' */  DelProgram(scr, NULL); /* remove all programs from memory, some might be			    Lock()'ed! */#ifdef AMIGA /* only amiga supports funclibs! */  CloseLib(scr, NULL, TRUE, &retval); /* force close of all funclibs */#endif  FREEALL();  FREEALLA();}/********************************************************************** * * int DelIdentifier() * * Delete an identifier from the hash table. Specify 'name' or 'ident'. * ******/ReturnCode REGARGSDelIdentifier(struct Data *scr,              uchar *name, /* only needed if 'ident' is NULL! */	      struct Identifier *ident){  ReturnCode ret=FPL_OK;  long i;  struct fplVariable *var;  if(!ident) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -