;========================================================== ; CompareStrings ; ; Check if the string RefString terminated by a char of SeparatorTable is contained ; in the string table StringTable ; Return #item in the table, or -1 if the string isn't in the table. First item is #0 ; Put in NextChar a ptr to the next char after RefString if NextChar != NULL ; ; input a0 StringTable ; a1 SeparatorTable ; a2 RefString ; a3 **char (NextChar) ; output d0.w #item, else <0 ; (a3) updated if a3 != 0 ; destroy d0-d2/a0 ;========================================================== butillib@0006: movem.l a1/a4,-(sp) ; Save RefString moveq.l #-1,d0 ; #item \ItemLoop: addq.w #1,d0 ; Update #item movea a2,a1 ; RefString \Loop: move.b (a0)+,d1 ; End of string in StringTable ? beq.s \CheckSeparator ; Yes, so check the separator at -1(a0) cmp.b (a1)+,d1 ; Compare strings beq.s \Loop ; Until mismatch \NextString: tst.b (a0)+ ; Else skip current string bne.s \NextString \CheckEOT: tst.b (a0) ; End of StringTable ? bne.s \ItemLoop ; No, continue moveq.l #-1,d0 ; Else return error code bra.s \NoSaveNextChar \CheckSeparator: move.b (a1),d1 ; Current char of RefString beq.s \Quit ; #0 ? So quit, EOF is always a valid separator movea.l (sp),a4 ; SeparatorTable \LoopSeparator: move.b (a4)+,d2 ; End of SeparatorTable ? beq.s \CheckEOT ; Yes, try with the next string cmp.b d1,d2 ; Equal ? bne.s \LoopSeparator ; No, test with next char \Quit: move.l a3,d1 ; Must save *NextChar ? beq.s \NoSaveNextChar ; No move.l a1,(a3) ; Else save it \NoSaveNextChar: movem.l (sp)+,a1/a4 rts
Les règles :
- d0-d2/a0-a1 peuvent être détruits, mais le résultat doit être dans d0.
- pas de smc ou de relogement
- les romcalls sont utilisables (mais bon... on parle optimisation ici

Les données :
a0 : StringTable -> une suite de chaines C suivies d'un 0 supplémentaires : dc.b "abc",0,"def",0,0
a1 : SeparatorTable -> une chaine C contenant les séparateurs acceptés : dc.b ":?!. \n",0. '\0' est toujours un séparateur valide.
a2 : RefString -> La chaine dont on cherche une correspondance dans StringTable
a3 : **char (NextChar) -> Adresse où l'on stocke l'adresse du séparateur marquant la fin de la chaine. On y enregistre rien si a3=NULL. On peut y stocker quelque chose même si on ne trouve pas de correspondance (ça sera donc invalide, mais le succès de la fonction est vérifié avec d0, ségatif si on a pas trouvé de chaine qui matche dans la table).
Bon d'après Zerosquare, c'est assez bien foutu, mais on pense pouvoir tirer encore quelques grammes ici ou là ^^