/*******************************************/ /* */ /* File: chtmlidfs.c */ /* Purpose: c2html identifier unit */ /* */ /* Author: Sfiligoi Igor */ /* */ /* Created : 25.03.1997 */ /* Last modified: 15.04.1997 */ /* */ /*******************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "chtmldefs.h" #include "chtmlidfs.h" typedef struct _hash_el { struct _hash_el *next; char *elstr; char *htmlname; char *elurl; } HASH_EL; #define HASH_EL_NR 211 typedef HASH_EL HASH_TABLE[HASH_EL_NR]; /* hash function */ int hash_func(char *elstr) { char *p; unsigned int h=0, g; for (p=elstr; *p != 0; p++) { h = (h<<4) + (*p); if ((g=h&0xf0000000)) /* assign to g */ { h = h ^ (g>>24); h = h ^ g; } } return h % HASH_EL_NR; } /* Init Routines */ void *hash_new() { HASH_TABLE *table; int i; table = (HASH_TABLE *) malloc(sizeof(HASH_TABLE)); for (i=0; i<HASH_EL_NR; i++) { /* the first ellement is dummy to preserve uniformity */ (*table)[i].next = NULL; (*table)[i].elstr = NULL; (*table)[i].htmlname = NULL; (*table)[i].elurl = NULL; } return table; } void hash_dispose(void *hash) { HASH_TABLE *table; int i; table = (HASH_TABLE *) hash; for (i=0; i<HASH_EL_NR; i++) { HASH_EL *hashel; for (hashel = (*table)[i].next; hashel!=NULL; hashel = (*table)[i].next) { (*table)[i].next=hashel->next; free(hashel->next); free(hashel->elstr); free(hashel->htmlname); free(hashel->elurl); } } } /* Delete an Idf */ void hash_del(void *hash, char *idfname) { HASH_TABLE *table; HASH_EL *hashel; unsigned int hash_nr; table = (HASH_TABLE *) hash; hash_nr = hash_func(idfname); for (hashel = &((*table)[hash_nr]); hashel->next!=NULL; hashel = hashel->next) if (strcmp(hashel->next->elstr,idfname)==0) { /* found, delete it */ HASH_EL *tmp_hashel; tmp_hashel = hashel->next; hashel->next = hashel->next->next; free(tmp_hashel->elstr); free(tmp_hashel->htmlname); free(tmp_hashel->elurl); return; } } /* Add Idf */ void hash_add(void *hash, char *idfname, char *htmlname) { HASH_TABLE *table; HASH_EL *hashel; unsigned int hash_nr; table = (HASH_TABLE *) hash; hash_nr = hash_func(idfname); hashel = (HASH_EL *) malloc(sizeof(HASH_EL)); hashel->elstr = (char *) malloc(strlen(idfname)+1); strcpy(hashel->elstr,idfname); if (htmlname==NULL) { hashel->htmlname = NULL; hashel->elurl = (char *) malloc(strlen(idfname)+2); sprintf(hashel->elurl,"#%s",idfname); } else { hashel->htmlname = normalize_dir(htmlname,chidir); if ((strchr(htmlname,'#')==NULL)&&(strchr(htmlname,'?')==NULL)) { /* a filename, needs the internal link */ char *tmpname; tmpname = normalize_dir(htmlname,outdir); hashel->elurl = (char *) malloc(strlen(tmpname)+strlen(idfname)+2); sprintf(hashel->elurl,"%s#%s",tmpname,idfname); free(tmpname); } else { /* already has all it needs */ hashel->elurl = normalize_dir(htmlname,outdir); } } hashel->next = (*table)[hash_nr].next; (*table)[hash_nr].next = hashel; } /* Search */ char *hash_find(void *hash, char *idfname) { HASH_TABLE *table; HASH_EL *hashel; unsigned int hash_nr; table = (HASH_TABLE *) hash; hash_nr = hash_func(idfname); for (hashel = (*table)[hash_nr].next; hashel!=NULL; hashel = hashel->next) if (strcmp(hashel->elstr,idfname)==0) return hashel->elurl; /* true, found */ return NULL; /* false, not found */ } /* hash IO */ char *hash_load(void *hash, char *filename) { FILE *hashfile; char *htmlname,*mainhtmlname,*tmpname; char idfname[1024]; int res,i; hashfile = fopen(filename,"r"); /* test if it is a real chi file */ fscanf(hashfile,"%s\n",idfname); if (strcmp(idfname,"CHI")!=0) { fprintf(stderr,"WARNING: %s not a CHI file, skipped!\n",filename); fclose(hashfile); return NULL; } mainhtmlname = (char *) malloc(4096); fscanf(hashfile,"%s\n",mainhtmlname); if (mainhtmlname[0]!='*') { /* there is a filename */ if (!((mainhtmlname[0]=='/')|| (((mainhtmlname[0]=='h')||(mainhtmlname[0]=='H'))&& ((mainhtmlname[1]=='t')||(mainhtmlname[1]=='T'))&& ((mainhtmlname[2]=='t')||(mainhtmlname[2]=='T'))&& ((mainhtmlname[3]=='p')||(mainhtmlname[3]=='P'))&& (mainhtmlname[4]==':')))) { /* must be trasformed in a path relative to the current dir */ char *dirname; int i; dirname = (char *) malloc(strlen(filename)+strlen(mainhtmlname)+1); /* worst case */ strcpy(dirname,filename); for(i=strlen(dirname)-1; dirname[i]!='/'; i--) dirname[i] = 0; strcat(dirname,mainhtmlname); free(mainhtmlname); mainhtmlname=dirname; } tmpname = mainhtmlname; mainhtmlname = normalize_dir(tmpname,outdir); free(tmpname); } else { /* no filename */ free(mainhtmlname); mainhtmlname=NULL; } htmlname = (char *) malloc(4096); for (res=fscanf(hashfile,"%s %s\n",idfname,htmlname); res!=EOF; res=fscanf(hashfile,"%s %s\n",idfname,htmlname)) { if (!((htmlname[0]=='/')|| (((htmlname[0]=='h')||(htmlname[0]=='H'))&& ((htmlname[1]=='t')||(htmlname[1]=='T'))&& ((htmlname[2]=='t')||(htmlname[2]=='T'))&& ((htmlname[3]=='p')||(htmlname[3]=='P'))&& (htmlname[4]==':')))) { /* must be trasformed in a path relative to the current dir */ char *dirname; int i; dirname = (char *) malloc(strlen(filename)+strlen(htmlname)+1); /* worst case */ strcpy(dirname,filename); for(i=strlen(dirname)-1; dirname[i]!='/'; i--) dirname[i] = 0; strcat(dirname,htmlname); free(htmlname); htmlname=dirname; } /* do not allow multiple copies */ hash_del(hash,idfname); hash_add(hash,idfname,htmlname); free(htmlname); htmlname = (char *) malloc(4096); } fclose(hashfile); return mainhtmlname; } void hash_save(void *hash, char *filename, char *htmlname) { FILE *hashfile; HASH_TABLE *table; char * norm_htmlname; int i; table = (HASH_TABLE *) hash; norm_htmlname = normalize_dir(htmlname,chidir); hashfile = fopen(filename,"w"); /* write idf */ fprintf(hashfile,"CHI\n"); fprintf(hashfile,"%s\n",norm_htmlname); for (i=0; i<HASH_EL_NR; i++) { HASH_EL *hashel; for (hashel=(*table)[i].next; hashel!=NULL; hashel=hashel->next) { if (hashel->htmlname!=NULL) fprintf(hashfile,"%s %s\n",hashel->elstr,hashel->htmlname); else fprintf(hashfile,"%s %s\n",hashel->elstr,norm_htmlname); } } free(norm_htmlname); fclose(hashfile); }