/****************************************************************************/ void /* */ tee_avain( /* */ int kentan_nro ,/* s Kent„n numero, joka muutetaan avaimeksi. */ Jasen_tyyppi *jasen /* s,t J„sen jonka tiedoista avain tehd„„n. */ ) /* ** Aliohjelmalla tehd„„n lajitteluavain j„senen tiedoista. ** Oletus: Avainkent„n koko v„hint„„n 20 tavua. ** ** Globaalit: JARJESTYS ** Kutsuu: kentan_tyyppi ** kentan_osoite ** kopioi_jono ** poista_tyhjat ----------------------------------------------------------------------------*/ { void *p; char s[20]; unsigned char *a; int i; double d; int tyyppi; /* Jollei kirjaintenmuunnostaulukkoa ole viel„ alustettu alustetaan se */ if (!JARJESTYS.alustettu) alusta_jarjestys(&JARJESTYS); /* Avainkent„n koko oltava v„hint„„n 16 merkki„ jotta reaaliluvut mahtuvat*/ i = sizeof(jasen->avain); if (i<20) { /* Otetaan kuitenkin varulta 20 merkki„ */ printf("TEE AVAIN: Liian pieni avainkentt„!\n"); return; } tyyppi = kentan_tyyppi(kentan_nro,jasen); /*Avaimen muoto riippuu tyypist„*/ p = kentan_osoite(kentan_nro,jasen); /*ja sis„lt” tietysti osoitteest*/ switch (tyyppi) { /* Tyypin muk.tehd. eri tavoin */ case Tjono: /* Merkkijonot */ kopioi_jono(N_S(jasen->avain),p); /* muutetaan kirjain kerrallaan */ poista_tyhjat(jasen->avain); /* kunhan turhat tyhj„ poistettu*/ for (a=(unsigned char *)jasen->avain; *a; a++) { *a = JARJESTYS.avainarvo[*a]; /* muunnetaan jonon seur. kirjai*/ } /* muunnostaulukon mukaisesti */ poista_tyhjat(jasen->avain); /* Koska saattanut tulla uusia */ return; case Tsotu: /* Sotussa 210493 -> 930421 */ kopioi_jono(N_S(s),p); liita_jono(N_S(s)," "); /* jotta v„h.6 mer*/ kopioi_jono(N_S(jasen->avain),s); /* Nyt avain v„h. 6 merkki„! */ jasen->avain[0] = s[4]; /* Vaihdetaan pv ja vuosi kesken„„n! */ jasen->avain[1] = s[5]; jasen->avain[4] = s[0]; jasen->avain[5] = s[1]; return; case Tint: /* Kok.luku 4 muotoon "+00004" */ i = *(int *)p; /* Kent„n sis„lt” i:hin */ sprintf(jasen->avain,"%+05d",i); /* muutetaan haluttuun muotoon */ if ( jasen->avain[0] == '-' ) jasen->avain[0]='+'-1; /* jotta - < + */ return; case Tdouble: /* Real.luku muot. "+0004.0000" */ d = *(double *)p; /* Kent„n sis„lt” d:hen */ sprintf(jasen->avain,"%+015.7lf",d); /* ja muutetaan haluttuun muot. */ if ( jasen->avain[0] == '-' ) /* ASCII + ja - '+' < '-', siis*/ jasen->avain[0]='+'-1; /* muutetaan jotta - < + */ return; default: /* Jos tyyppi tuntematon */ printf("TEE AVAIN: Ei ole kentt„„ %d!\n",kentan_nro); return; } } /****************************************************************************/ static Vertailu_tyyppi EHDOT[] = { { "" , 0, YHT}, /* Tuntemattomat ehdot WILDMAT tyyliin (sama ==) */ { "==", 2, YHT}, { "!=", 2, ERIS}, { "<=", 2, PIENYHT}, { "<" , 1, PIEN}, { ">=", 2, SUURYHT}, { ">" , 1, SUUR}, { NULL, 0, YHT} }; /****************************************************************************/ int /* 1 = ei t„sm„„ */ tutki_tasmaako( /* 0 = t„sm„„ */ Jasen_tyyppi *jasen ,/* s Tutkittva j„sen */ char *ikentta ,/* s Kentt„ muutettuna isoiksi kirjaimeksi */ char *maski ,/* s Maski muutettuna isoiksi kirjaimeksi */ int knro /* s Kent„n numero. */ ) /* ** Funktiolla tutkitaan onko annettu ehto voimassa. Ehdot: ** <, <= ,> , >= , !=, == ** Mik„li ehtoa ei ole annettu, tulkitaan ehto tavalliseksi ** wildmat vertailuksi. ** ** Globaalit: EHDOT ** Muuttuu: jasen->avain ** Kutsuu: kentta_jonoksi ** jono_kentaksi ** wildmat ** Esimerkki: ikentta "20", maski "<=50" -> 0 (on totta, eli t„sm„„) ----------------------------------------------------------------------------*/ { int i,tulos,ehto_ind=0; char *m; Jasen_tyyppi mjasen; /* Etsit„„n hakuehdon alusta onko ehtoa */ for (i=1; EHDOT[i].ehto; i++) /* K„yd„„n kaikki ehdot l„pi */ if ( strstr(maski,EHDOT[i].ehto) == maski ) { /* jos on niin l”ytyi ja */ ehto_ind = i; break; /* talletetaan ehdon numero sek„ pois */ } m = maski+EHDOT[ehto_ind].pit; /* Siirryt„„n jonossa ehdon ohi */ switch ( EHDOT[ehto_ind].kasky ) { /* L”ytyneen ehdon toimannan mukaan */ case YHT: /* Jos == tai ei ehtoa */ return wildmat(ikentta,m); /* niin kokeillaan wildmat:ll„ onko OK*/ case ERIS: /* Jos != niin */ return !wildmat(ikentta,m); /* tulos wildmat p„invastaisena */ case PIEN: /* Ep„yht„l”ist„ */ case PIENYHT: /* muutetaan kentt„ ensin lajittelu */ case SUUR: /* avaimeksi, jota voidaan verrata */ case SUURYHT: /* merkkijonon suuruutena */ jono_kentaksi(knro,&mjasen,m); /* maski muutetaan apuj„seneen */ tee_avain(knro,&mjasen); /* avaimeksi */ tee_avain(knro,jasen); /* ja itse kentt„ toiseen j„seneen */ tulos = strcmp(jasen->avain,mjasen.avain); /* verrataan avaimia */ switch ( EHDOT[ehto_ind].kasky ) { /* Ep„yht„l”n mukaan muutetaan tul.*/ case PIEN: return !(tulos<0); /* < pal.tosi jos strcmp-> -1 */ case PIENYHT: return !(tulos<=0);/* <= pal.tosi jos strcmp-> -1 v 0 */ case SUUR: return !(tulos>0); /* > pal.tosi jos strcmp-> 1 */ case SUURYHT: return !(tulos>=0);/* >= pal.tosi jos strcmp-> 1 v 0 */ } /* ja tosihan oli t„ll„ kertaa 0! */ default: /* Tuntemattomista ehdoista -> ei t„sm*/ return 1; } } /****************************************************************************/ void /* */ tee_avain( /* */ int kentan_nro ,/* s Kent„n numero, joka muutetaan avaimeksi. */ Jasen_tyyppi *jasen /* s,t J„sen jonka tiedoista avain tehd„„n. */ ) /* ** Aliohjelmalla tehd„„n lajitteluavain j„senen tiedoista. ** Oletus: Avainkent„n koko v„hint„„n 20 tavua. ** ** Globaalit: JARJESTYS ** Kutsuu: kentan_tyyppi ** kentan_osoite ** kopioi_jono ** poista_tyhjat ----------------------------------------------------------------------------*/ { void *p; char s[20]; unsigned char *a; int i; double d; int tyyppi; if (!JARJESTYS.alustettu) alusta_jarjestys(&JARJESTYS); i = sizeof(jasen->avain); if (i<20) { printf("TEE AVAIN: Liian pieni avainkentt„!\n"); return; } tyyppi = kentan_tyyppi(kentan_nro,jasen); p = kentan_osoite(kentan_nro,jasen); switch (tyyppi) { case Tjono: kopioi_jono(N_S(jasen->avain),p); poista_tyhjat(jasen->avain); for (a=(unsigned char *)jasen->avain; *a; a++) { *a = JARJESTYS.avainarvo[*a]; } poista_tyhjat(jasen->avain); return; case Tsotu: kopioi_jono(N_S(s),p); liita_jono(N_S(s)," "); kopioi_jono(N_S(jasen->avain),s); jasen->avain[0] = s[4]; /* Vaihdetaan pv ja vuosi kesken„„n! */ jasen->avain[1] = s[5]; jasen->avain[4] = s[0]; jasen->avain[5] = s[1]; return; case Tint: i = *(int *)p; sprintf(jasen->avain,"%+05d",i); if ( jasen->avain[0] == '-' ) jasen->avain[0]='+'-1; /* jotta - < + */ return; case Tdouble: d = *(double *)p; sprintf(jasen->avain,"%+015.7lf",d); if ( jasen->avain[0] == '-' ) jasen->avain[0]='+'-1; /* jotta - < + */ return; default: printf("TEE AVAIN: Ei ole kentt„„ %d!\n",kentan_nro); return; } }