int isoverloadable_op(char *str) /*;isoverloadable_op*/ { /* Check whether a string represnts an overloadable operator by * comparing against all overloadable operators. */ char tmp[MAXLINE + 1]; int i; strcpy(tmp, str); convtolower(tmp); for (i = 0; i < NUMOVERLOADOPS; i++) if (!strcmp(tmp, overloadable_operators[i])) return(1); return(0); }
// GESTION DES TABLES DE HACHAGE // Méthode à 2 clés (adr+fil), 2e cle facultative // hash[no_enregistrement][pos]->hash est un index dans le tableau général liens // #define HTS_HASH_SIZE 8191 (premier si possible!) // type: numero enregistrement - 0 est case insensitive (sav) 1 (adr+fil) 2 (former_adr+former_fil) // recherche dans la table selon nom1,nom2 et le no d'enregistrement // retour: position ou -1 si non trouvé int hash_read(const hash_struct* hash,char* nom1,char* nom2,int type,int normalized) { char BIGSTK normfil_[HTS_URLMAXSIZE*2]; char catbuff[CATBUFF_SIZE]; char* normfil; char* normadr; unsigned int cle; int pos; // calculer la clé de recherche, non modulée if (type) cle = hash_cle(nom1,nom2); else cle = hash_cle(convtolower(catbuff,nom1),nom2); // case insensitive // la position se calcule en modulant pos = (int) (cle%HTS_HASH_SIZE); // entrée trouvée? if (hash->hash[type][pos] >= 0) { // un ou plusieurs enregistrement(s) avec une telle clé existe.. // tester table de raccourcis (hash) // pos est maintenant la position recherchée dans liens pos = hash->hash[type][pos]; while (pos>=0) { // parcourir la chaine switch (type) { case 0: // sav if (strfield2(nom1,hash->liens[pos]->sav)) { // case insensitive #if DEBUG_HASH==2 printf("hash: found shortcut at %d\n",pos); #endif return pos; } break; case 1: // adr+fil { if (!normalized) normfil=hash->liens[pos]->fil; else normfil=fil_normalized(hash->liens[pos]->fil,normfil_); if (!normalized) normadr = jump_identification(hash->liens[pos]->adr); else normadr = jump_normalized(hash->liens[pos]->adr); if ((strfield2(nom1,normadr)!=0) && (strcmp(nom2,normfil)==0)) { #if DEBUG_HASH==2 printf("hash: found shortcut at %d\n",pos); #endif return pos; } } break; case 2: // former_adr+former_fil { if (hash->liens[pos]->former_adr) { if (!normalized) normfil=hash->liens[pos]->former_fil; else normfil=fil_normalized(hash->liens[pos]->former_fil,normfil_); if (!normalized) normadr = jump_identification(hash->liens[pos]->former_adr); else normadr = jump_normalized(hash->liens[pos]->former_adr); if ((strfield2(nom1,normadr)!=0) && (strcmp(nom2,normfil)==0)) { #if DEBUG_HASH==2 printf("hash: found shortcut at %d\n",pos); #endif return pos; } } } break; } // calculer prochaine position dans la chaine { int old=pos; pos=hash->liens[pos]->hash_next[type]; // sinon prochain dans la chaine if (old==pos) pos=-1; // erreur de bouclage (ne devrait pas arriver) } } // Ok va falloir chercher alors.. /*pos=hash->max_lien; // commencer à max_lien switch (type) { case 0: // sav while(pos>=0) { if (hash->liens[pos]->hash_sav == cle ) { if (strcmp(nom1,hash->liens[pos]->sav)==0) { hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos; // noter plus récent dans shortcut table #if DEBUG_HASH==2 printf("hash: found long search at %d\n",pos); #endif return pos; } } pos--; } break; case 1: // adr+fil while(pos>=0) { if (hash->liens[pos]->hash_adrfil == cle ) { if ((strcmp(nom1,hash->liens[pos]->adr)==0) && (strcmp(nom2,hash->liens[pos]->fil)==0)) { hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos; // noter plus récent dans shortcut table #if DEBUG_HASH==2 printf("hash: found long search at %d\n",pos); #endif return pos; } } pos--; } break; case 2: // former_adr+former_fil while(pos>=0) { if (hash->liens[pos]->hash_fadrfil == cle ) { if (hash->liens[pos]->former_adr) if ((strcmp(nom1,hash->liens[pos]->former_adr)==0) && (strcmp(nom2,hash->liens[pos]->former_fil)==0)) { hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos; // noter plus récent dans shortcut table #if DEBUG_HASH==2 printf("hash: found long search at %d\n",pos); #endif return pos; } } pos--; } }*/ #if DEBUG_HASH==1 printf("hash: not found after test %s%s\n",nom1,nom2); #endif return -1; // non trouvé } else { #if DEBUG_HASH==2 printf("hash: not found %s%s\n",nom1,nom2); #endif return -1; // non trouvé : clé non entrée (même une fois) } }
/* Key sav hashes are using case-insensitive version */ static inthash_keys key_sav_hashes(void *arg, const char *value) { hash_struct *const hash = (hash_struct*) arg; convtolower(hash->catbuff, value); return inthash_hash_value(hash->catbuff); }
// enregistrement lien lpos dans les 3 tables hash1..3 void hash_write(hash_struct* hash,int lpos,int normalized) { char BIGSTK normfil_[HTS_URLMAXSIZE*2]; char catbuff[CATBUFF_SIZE]; char* normfil; unsigned int cle; int pos; int* ptr; // if (hash->liens[lpos]) { // on sait jamais.. hash->max_lien = max(hash->max_lien,lpos); #if DEBUG_HASH hashnumber=hash->max_lien; #endif // élément actuel sur -1 (fin de chaine) hash->liens[lpos]->hash_next[0]=hash->liens[lpos]->hash_next[1]=hash->liens[lpos]->hash_next[2]=-1; // cle = hash_cle(convtolower(catbuff,hash->liens[lpos]->sav),""); // CASE INSENSITIVE pos = (int) (cle%HTS_HASH_SIZE); ptr = hash_calc_chaine(hash,0,pos); // calculer adresse chaine *ptr = lpos; // noter dernier enregistré #if DEBUG_HASH==3 printf("[%d",pos); #endif // if (!normalized) normfil=hash->liens[lpos]->fil; else normfil=fil_normalized(hash->liens[lpos]->fil,normfil_); if (!normalized) cle = hash_cle(jump_identification(hash->liens[lpos]->adr),normfil); else cle = hash_cle(jump_normalized(hash->liens[lpos]->adr),normfil); pos = (int) (cle%HTS_HASH_SIZE); ptr = hash_calc_chaine(hash,1,pos); // calculer adresse chaine *ptr = lpos; // noter dernier enregistré #if DEBUG_HASH==3 printf(",%d",pos); #endif // if (hash->liens[lpos]->former_adr) { // former_adr existe? if (!normalized) normfil=hash->liens[lpos]->former_fil; else normfil=fil_normalized(hash->liens[lpos]->former_fil,normfil_); if (!normalized) cle = hash_cle(jump_identification(hash->liens[lpos]->former_adr),normfil); else cle = hash_cle(jump_normalized(hash->liens[lpos]->former_adr),normfil); pos = (int) (cle%HTS_HASH_SIZE); ptr = hash_calc_chaine(hash,2,pos); // calculer adresse chaine *ptr = lpos; // noter dernier enregistré #if DEBUG_HASH==3 printf(",%d",pos); #endif } #if DEBUG_HASH==3 printf("] "); fflush(stdout); #endif } #if DEBUT_HASH else { printf("* hash_write=0!!\n"); abortLogFmt("unexpected error in hash_write (pos=%d)" _ pos); exit(1); } #endif // }
/* Key sav hashes are using case-insensitive version */ static coucal_hashkeys key_sav_hashes(void *arg, coucal_key_const key) { hash_struct *const hash = (hash_struct*) arg; convtolower(hash->catbuff, (const char*) key); return coucal_hash_string(hash->catbuff); }