/* Aliohjelmia NCD:n TREEINFO.NCD -tiedoston lukemiseksi. Tiedoston muoto: Tavut 0-4 : "PNCI" Tavut 5-6 : Hakemistojen lkm Tavut 7-8 : ??? Tavut 9-?? : Hakemistoja 16 tavun ryhmiss„ Tavut nn-nn+1 : ??? Hakemiston kohdalla: Tavut 0-10 : Hakemiston nimi Tavut 11-12 : ??? Tavu 13 : Hakemiston syvyystaso puussa \ = 0 Tavu 14 : 0 = sisar yl„puolella Tavu 15 : 1 = sisar alapuolella Olkoon hakemisto: \ ÄĀÄAUKOT ĆÄKOEÄÄÄÄÄÄÄÄÄĀÄKOE1 ³ ĆÄKOE2ÄÄÄÄÄÄÄÄĀÄKOE2-1 ³ ³ ĆÄKOE2-2ÄÄÄÄÄÄĀÄKOE2-2-1 ³ ³ ³ ĄÄKOE2-2-2 ³ ³ ĆÄKOE2-3 ³ ³ ĄÄKOE2-4 ³ ĄÄKOE3 ĆÄLUOKKA ĆÄMONIPS ĆÄOMA ĆÄPESA ĄÄSYSÄÄÄÄÄÄÄÄÄÄÄDISPLAYÄÄÄÄÄÄÄTIGA Kutsu: vaihtaa hakemistoon hakumaski ncd haku --------------------------------------------------------------------------- \ \ \o \oma \ o + \ota \oma \ ota + \ot* - ei l”ydy \ ot* \d - ei l”ydy \ d + \*\d \sys\display \ * d + \*\do \sys\display \ * do + \*\do* - ei l”ydy \ * do* *2-2\*-1 \koe\koe2\koe2-2\koe2-2-1 *2-2 *-1 \*2-2\*-1 - ei l”ydy \ *2-2 *-1 \\d \sys\display \ * d + \koe1 \koe \ koe1 + *\\k \koe\koe1 * * k + --------------------------------------------------------------------------- */ #include #include #include #include #include #include "ncdread.h" #include "mjonot.h" #define NCDNAME "\\treeinfo.ncd" #define MAXDIRS 1500 #define MALLOC /* Määrää tuleeko muisti allokoimalla vain staattisesti */ #ifdef N_MJONOT /****************************************************************************/ int /* */ wildmat( /* 0 = jono t„sm„„ maskiin */ /* 1 = jono ei t„sm„„ maskiin */ register const char *s ,/* s Tutkittava jono */ register const char *p /* s Maski, johon jonoa verrataan */ ) /* ** Funktiolla tutkitaan t„sm„„k” annettu jono verrattavaan maskiin. ** Maski saa sis„lt„„ seuraavia erikoismerkkej„: ** * vastaa 0-n merkki„ ** ? vastaa mit„ tahansa yht„ merkki„ ** ** Algoritmi: Kysymysmerkki ja tavallinen kirjain normaalisti ** Jos tulee vastaan t„hti joka ei ole jonon lopussa, ** niin ongelmahan on oikeastaan ** (koska t„h„n asti kaikki on ollut oikein) ** "Onko loppujono sama kuin toisen jonon loppu JOSTAKIN ** kohdasta alkaen"? ** Siis kokeillaan sovittaa loppujonoa aliohjelman itsens„ ** (rekursio) avulla kaikkiin mahdollisiin loppupaikkoihin. ** Esimerkki: s = "Kissa" p = "*ss*" -> 0 ** = "*ss" -> 1 ----------------------------------------------------------------------------*/ { while (*p) { /* Jos kokeiltavaa jonoa on j„ljell„ */ if (*p == '?') { /* Jos kysymysmerkki, niin kaikki kelpaa */ if (!*s) return 1; /* paitsi jos jono on loppunut! */ } else if (*p == '*') { /* Jos * niin katsotaan onko viimeinen */ if (*++p) /* Jollei * viimeinen, niin kokeillaan */ while (wildmat(s, p)) /* loppujonoa jokaiseen eri paikkaan. */ if (!*++s) return 1; /* Jos jono loppuu kesken niin ei t„sm„„! */ return 0; /* Muuten samat (* viimeinen tai loppujono*/ } /* t„sm„si) */ else if (*s != *p) /* Jos samat merkit niin tietysti OK! */ return 1; s++; p++; /* Kummassakin jonossa eteenp„in */ } return *s; /* Jos jono loppui yht„aikaa, niin OK! */ } /****************************************************************************/ char /* */ isoksi( /* Muutetaan kirjain vast. isoksi kirjaimeksi. */ char c /* s Muutettava kirjain. */ ) /* ** Funktiolla muutetaan pienet kirjaimet isoiksi. My”s skandit toimivat ** Algoritmi: K„sitell„„n skandit erikoistapauksena. ----------------------------------------------------------------------------*/ { switch (c) { case '†': return '¸'; case '„': return 'ˇ'; case '”': return '™'; } /* N„in: if ( c<'a' ) return c; if ( c>'z' ) return c; return c-('a'-'A'); tai: */ return toupper(c); } /****************************************************************************/ char /* */ *jono_isoksi( /* Muutetaan jono isoilla kirjoitetuksi. */ char *jono /* s,t Muutettava jono. */ ) /* ** Funktiolla muutetaan merkkijonon pienet kirjaimet isoiksi. My”s skandit. ** Kutsuu: isoksi ----------------------------------------------------------------------------*/ { char *p; for (p=jono; *p; p++) *p=isoksi(*p); return jono; } /****************************************************************************/ char /* */ *palanen( /* Osoitin merkkijonon palaseen. */ char *jono ,/* s P„tkitt„v„ jono, turmeltuu! */ char *erottimet ,/* s Merkit joiden kohdalta katkaistaan. */ int *jaljella /* t Paljonko jonoa on viel„ j„ljell„ (-1 loppu)*/ ) /* ** Funktiolla p„tkit„„n merkkijonoa osiin. 1. kutsukerralla v„litet„„n ** tutkittava jono ja t„m„n j„lkeen seuraavilla NULL osoitin. ** Funktio vaihtaa l”yt„m„ns„ erotinmerkti NUL-merkeiksi! ** ** Muuttuu: jono ** Algoritmi: ** Esimerkki: 012345678901234 ** jono="Aku|Ankka||12" erottimet="|" ** 1. kutsu palanen(jono,"|",&j) -> "Aku" , j=9 ** 2. kutsu palanen(NULL,"|",&j) -> "Ankka", j=3 ** 3. kutsu palanen(NULL,"|",&j) -> "" , j=2 ** 4. kutsu palanen(NULL,"|",&j) -> "12" , j=0 ** 5. kutsu palanen(NULL,"|",&j) -> "" , j=-1 ----------------------------------------------------------------------------*/ { static char *st; static int p1,p2,pit; if (jono) { /* 1. kutsukerta, alustetaan apumuuttujat */ st = jono; pit = strlen(jono); p1 = 0; } else p1 = p2+1; /* Muilla kerroilla jatketaan siit„ mihin viim. j„„tiin. */ if ( p1 > pit ) { *jaljella = -1; return st+pit; /* Tyhj„ merkkijono, kun osoitetaan jonon NUL-tavuun. */ } p2 = p1+strcspn(st+p1,erottimet); st[p2] = 0; *jaljella = pit-p2; return st+p1; } #endif /****************************************************************************/ typedef struct { char name[13]; char level; char NoPrevSister; char NextSister; } OneDirType; typedef struct { char name[5]; int DirCount; int unknown; } NCDHeaderType; typedef struct { NCDHeaderType header; OneDirType Dirs[MAXDIRS]; } NCD_type; typedef struct { int n; char *Levels[20]; char PathName[100]; } PathType; static PathType Dir; static PathType Find; static struct { int NCD; /* Onko NCD -vertaus eli vain sanan alku */ int level; /* Mist„ hakemsitosta NCD vertaus */ int ch; /* Mik„ viimeinen. NCD-vertauksen kirjain */ int len; /* Monellekko kirjaimelle NCD-vertaus */ int exact; /* Apum kun halutaan justiinsa sama loppu */ } Haku; NCD_type *NCD; #ifndef MALLOC NCD_type GNCD; #endif static char drive[MAXDRIVE]; static char NCDname[30]; /****************************************************************************/ const char *getNCD(const char *s) { char dir[MAXDIR]; char file[MAXFILE]; char ext[MAXEXT]; //int flags; int ni; //flags= fnsplit(s,drive,dir,file,ext); ni = strlen(drive); strcpy(NCDname,drive); strcat(NCDname,NCDNAME); return s+ni; } /****************************************************************************/ NCD_type *ReadNCD(const char **name) { FILE *f; NCD_type *NCD; *name=getNCD(*name); f = fopen(NCDname,"rb"); if ( !f ) return NULL; #ifdef MALLOC NCD = (NCD_type *)malloc(sizeof(NCD_type)); #else NCD = &GNCD; #endif if ( !NCD ) { fclose(f); return NULL; } fread(&NCD->header,sizeof(NCD->header),1,f); NCD->header.DirCount=min(MAXDIRS,NCD->header.DirCount); fread(&NCD->Dirs,sizeof(NCD->Dirs[0]),min(MAXDIRS,NCD->header.DirCount),f); fclose(f); return NCD; } /****************************************************************************/ int FindThis(int level,int ind) { int i; for (i=ind; i>=0; i--) if (NCD->Dirs[i].level==level) return i; return 0; } /****************************************************************************/ int DoPathName(int ind,int dopath) { int i,li; int level = NCD->Dirs[ind].level; if ( ind < 0 ) return ind; Dir.n = level+1; li = ind; if ( dopath == 2 ) for (i=level; i>=0; i--) Dir.Levels[i]=NCD->Dirs[li=FindThis(i,li)].name; else Dir.Levels[level]=NCD->Dirs[ind].name; if ( dopath != 1 ) return ind; strcpy(Dir.PathName,drive); strcat(Dir.PathName,"\\"); for (i=1; i<=level; i++) { strcat(Dir.PathName,Dir.Levels[i]); strcat(Dir.PathName,"\\"); } return ind; } /****************************************************************************/ int NCDcmp(void) { int i,alku; alku = Dir.n - Find.n; if ( alku < 0 ) return 1; for (i=0; i < Haku.level; i++ ) { if ( wildmat(Dir.Levels[alku+i],Find.Levels[i]) ) return 1; } for (i=Haku.level; i=0 ) { if ( !*p ) if ( n ) p = "*"; else break; Find.Levels[Find.n++]=p; p = palanen(NULL,"\\",&n); } Haku.NCD = 0; Haku.level = Find.n; Haku.len = 0; Haku.ch = 0; if ( allow_NCD && ( Find.n > 0 ) && ( strpbrk(Find.Levels[Find.n-1],"*?")==0 ) ) { Haku.level = Find.n-1; Haku.NCD = 1; Haku.ch = 0; Haku.len = strlen(Find.Levels[Haku.level]); } return Find.n; } /****************************************************************************/ int FindNCDIndDF(int n1,int n2) { int ind; ind = FindNCDInd2(n1,NCD->header.DirCount); if ( ind >= 0 ) return ind; ind = FindNCDInd2(0,n2); if ( ind >= 0 ) return ind; return -1; } /****************************************************************************/ int FindNCDInd(int n,const char *s,int allow_NCD) { int ind,best; Haku.exact = 0; SplitToFind(s,allow_NCD); ind = best = FindNCDIndDF(n,n); if ( !Haku.NCD ) return ind; while ( ind >= 0 && ++Haku.ch < Haku.len ) { best = ind; ind = FindNCDIndDF(best,n); } if ( ind >= 0 ) { /* Tutkitaan l”ytyyk” viel„ just sama */ best = ind; Haku.exact = 1; ind = FindNCDIndDF(best,n); if ( ind >= 0 ) best = ind; } return best; } static int start_index = -1; /****************************************************************************/ const char *FindNCD(const char *sname,const char *name,int cont) { int i; char findname[200]; char usname[100]; kopioi_jono(N_S(findname),name); kopioi_jono(N_S(usname),sname); jono_isoksi(usname); jono_isoksi(findname); NCD = ReadNCD(&name); if ( !NCD ) return ""; if ( !cont ) { start_index = -1; if ( usname[0] ) start_index = FindNCDInd(0,usname,0); } i = FindNCDInd(start_index+1,findname,1); if ( i < 0 ) Dir.PathName[0] = 0; start_index = i; ret: #ifdef MALLOC free(NCD); #endif return Dir.PathName; } static char OldS[200]; static int FirstStart=-1; /****************************************************************************/ const char *FindFirstDir(const char *st,const char *s) { const char *p; start_index = -1; strcpy(OldS,s); p = FindNCD(st,OldS,0); FirstStart = start_index; return p; } /****************************************************************************/ const char *FindNextDir(void) { const char *p; p = FindNCD("",OldS,1); if ( start_index == FirstStart ) { start_index--; return ""; } return p; } #ifdef NCDREADMAIN /****************************************************************************/ int main(int argc, char *argv[]) { char *s,*st,*p; if ( argc < 2 ) s = ""; else s = argv[1];; if ( argc < 3 ) st = ""; else st = argv[2];; p = FindFirstDir(st,s); while ( *p ) { printf("%s\n",p); p = FindNextDir(); } return 0; } #endif