hschumann2/TempleOS-Source-Code
0847
1 2U8 *StrPrintHex(U8 *dst,I64 num;I64 width)3{4 U8 *res=dst+width;5 dst=res;6 while (width--) {7 *--dst="0123456789ABCDEF"(U8 *)[num&15];8 num>>=4;9 }10 return res;11}12 13U0 PutHex(I64 num,I64 width)14{15 U8 buf[17];16 if (width>16) width=16;17 *StrPrintHex(buf,num,width)=0;18 "%s",buf;19}20 21asm {22// IN: RAX=NUM TO PRINT23PUT_HEX_U64::24 PUSH_C_REGS25 PUSH 1626 PUSH RAX27 CALL &PutHex28 POP_C_REGS29 RET30PUT_HEX_U32::31 PUSH_C_REGS32 PUSH 833 PUSH RAX34 CALL &PutHex35 POP_C_REGS36 RET37PUT_HEX_U16::38 PUSH_C_REGS39 PUSH 440 PUSH RAX41 CALL &PutHex42 POP_C_REGS43 RET44PUT_HEX_U8::45 PUSH_C_REGS46 PUSH 247 PUSH RAX48 CALL &PutHex49 POP_C_REGS50 RET51PUT_CHARS::52// IN: RAX=Char53 PUSH_C_REGS54 PUSH RAX55 CALL &PutChars56 POP_C_REGS57 RET58PUT_STR::59// IN: RSI=String60 PUSH_C_REGS61 PUSH RSI62 CALL &PutS63 POP_C_REGS64 RET65_STRCPY::66 PUSH RBP67 MOV RBP,RSP68 PUSH RSI69 PUSH RDI70 MOV RDI,U64 SF_ARG1[RBP]71 TEST RDI,RDI72 JZ @@1573 MOV RSI,U64 SF_ARG2[RBP]74 TEST RSI,RSI75 JNZ @@0576 XOR RAX,RAX77 JMP @@1078@@05: LODSB79@@10: STOSB80 TEST AL,AL81 JNZ @@0582@@15: POP RDI83 POP RSI84 POP RBP85 RET1 1686_STRCMP::87 PUSH RBP88 MOV RBP,RSP89 PUSH RSI90 PUSH RDI91 MOV RSI,U64 SF_ARG2[RBP]92 MOV RDI,U64 SF_ARG1[RBP]93@@05: LODSB94 TEST AL,AL95 JZ @@2096 SCASB97 JE @@0598 JA @@1599@@10: MOV RAX,1100 JMP @@25101@@15: MOV RAX,-1102 JMP @@25103@@20: SCASB104 JNE @@10105 XOR RAX,RAX106@@25: POP RDI107 POP RSI108 POP RBP109 RET1 16110TO_UPPER::111 CMP AL,'a'112 JB @@05113 CMP AL,'z'114 JA @@05115 ADD AL,'A'-'a'116@@05: RET117_STRICMP::118 PUSH RBP119 MOV RBP,RSP120 PUSH RSI121 PUSH RDI122 MOV RSI,U64 SF_ARG2[RBP]123 MOV RDI,U64 SF_ARG1[RBP]124@@05: LODSB125 TEST AL,AL126 JZ @@30127 CMP AL,'a'128 JB @@10129 CMP AL,'z'130 JA @@10131 ADD AL,'A'-'a'132@@10: MOV BL,U8 [RDI]133 INC RDI134 CMP BL,'a'135 JB @@15136 CMP BL,'z'137 JA @@15138 ADD BL,'A'-'a'139@@15: CMP AL,BL140 JE @@05141 JA @@25142@@20: MOV RAX,1143 JMP @@35144@@25: MOV RAX,-1145 JMP @@35146@@30: MOV BL,U8 [RDI]147 TEST BL,BL148 JNE @@20149 XOR RAX,RAX150@@35: POP RDI151 POP RSI152 POP RBP153 RET1 16154_STRNCMP::155 PUSH RBP156 MOV RBP,RSP157 PUSH RSI158 PUSH RDI159 MOV RCX,U64 SF_ARG3[RBP]160 MOV RSI,U64 SF_ARG2[RBP]161 MOV RDI,U64 SF_ARG1[RBP]162@@05: TEST RCX,RCX163 JZ @@25164 DEC RCX165 LODSB166 TEST AL,AL167 JZ @@20168 SCASB169 JE @@05170 JA @@15171@@10: MOV RAX,1172 JMP @@30173@@15: MOV RAX,-1174 JMP @@30175@@20: MOV BL,U8 [RDI]176 TEST BL,BL177 JNE @@10178@@25: XOR RAX,RAX179@@30: POP RDI180 POP RSI181 POP RBP182 RET1 24183_STRNICMP::184 PUSH RBP185 MOV RBP,RSP186 PUSH RSI187 PUSH RDI188 MOV RCX,U64 SF_ARG3[RBP]189 MOV RSI,U64 SF_ARG2[RBP]190 MOV RDI,U64 SF_ARG1[RBP]191@@05: TEST RCX,RCX192 JZ @@35193 DEC RCX194 LODSB195 TEST AL,AL196 JZ @@30197 CMP AL,'a'198 JB @@10199 CMP AL,'z'200 JA @@10201 ADD AL,'A'-'a'202@@10: MOV BL,U8 [RDI]203 INC RDI204 CMP BL,'a'205 JB @@15206 CMP BL,'z'207 JA @@15208 ADD BL,'A'-'a'209@@15: CMP AL,BL210 JE @@05211 JA @@25212@@20: MOV RAX,1213 JMP @@40214@@25: MOV RAX,-1215 JMP @@40216@@30: SCASB217 JNE @@20218@@35: XOR RAX,RAX219@@40: POP RDI220 POP RSI221 POP RBP222 RET1 24223_STRMATCH::224 PUSH RBP225 MOV RBP,RSP226 PUSH RSI227 PUSH RDI228 MOV RSI,U64 SF_ARG2[RBP]229 TEST RSI,RSI230 JZ @@25231 MOV RDI,U64 SF_ARG1[RBP]232 TEST RDI,RDI233 JZ @@25234 MOV DL,U8 [RDI]235 TEST DL,DL236 JZ @@20237 JMP @@10238@@05: INC RSI239@@10: LODSB240 TEST AL,AL241 JZ @@25242 CMP AL,DL243 JNE @@10244 DEC RSI245 MOV RCX,1246@@15: MOV AL,U8 [RDI+RCX]247 TEST AL,AL248 JZ @@20249 CMP AL,U8 [RSI+RCX]250 JNE @@05251 INC RCX252 JMP @@15253 254 DEC RSI255@@20: MOV RAX,RSI256 JMP @@30257@@25: XOR RAX,RAX258@@30: POP RDI259 POP RSI260 POP RBP261 RET1 16262_STRIMATCH::263 PUSH RBP264 MOV RBP,RSP265 PUSH RSI266 PUSH RDI267 MOV RSI,U64 SF_ARG2[RBP]268 TEST RSI,RSI269 JZ @@25270 MOV RDI,U64 SF_ARG1[RBP]271 TEST RDI,RDI272 JZ @@25273 MOV AL,U8 [RDI]274 CALL TO_UPPER275 MOV DL,AL276 TEST DL,DL277 JZ @@20278 JMP @@10279@@05: INC RSI280@@10: LODSB281 CALL TO_UPPER282 TEST AL,AL283 JZ @@25284 CMP AL,DL285 JNE @@10286 DEC RSI287 MOV RCX,1288@@15: MOV AL,U8 [RDI+RCX]289 CALL TO_UPPER290 TEST AL,AL291 JZ @@20292 MOV BL,U8 [RSI+RCX]293 XCHG AL,BL294 CALL TO_UPPER295 CMP AL,BL296 JNE @@05297 INC RCX298 JMP @@15299 300 DEC RSI301@@20: MOV RAX,RSI302 JMP @@30303@@25: XOR RAX,RAX304@@30: POP RDI305 POP RSI306 POP RBP307 RET1 16308}309_extern _STRCMP I64 StrCmp(310 U8 *st1,U8 *st2); //Compare two strings.311_extern _STRICMP I64 StrICmp(312 U8 *st1,U8 *st2); //Compare two strings, ignoring case.313_extern _STRNCMP I64 StrNCmp(314 U8 *st1,U8 *st2,I64 n); //Compare N bytes in two strings.315_extern _STRNICMP I64 StrNICmp(316 U8 *st1,U8 *st2,I64 n); //Compare N bytes in two strings, ignoring case.317_extern _STRMATCH U8 *StrMatch(318 U8 *needle,U8 *haystack_str); //Scan for string in string.319_extern _STRIMATCH U8 *StrIMatch(320 U8 *needle,U8 *haystack_str);//Scan for string in string, ignoring case.321_extern _STRCPY U0 StrCpy(322 U8 *dst,U8 *src); //Copy string.323 324//These bitmaps go to 0-511 so that Lex() can use them with Token Codes.325U32326 char_bmp_alpha[16]=327 {0x0000000,0x00000000,0x87FFFFFF,0x07FFFFFE,328 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,329 0,0,0,0,0,0,0,0},330 331 char_bmp_alpha_numeric[16]=332 {0x0000000,0x03FF0000,0x87FFFFFF,0x07FFFFFE,333 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,334 0,0,0,0,0,0,0,0},335 336 char_bmp_alpha_numeric_no_at[16]=337 {0x0000000,0x03FF0000,0x87FFFFFE,0x07FFFFFE,338 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,339 0,0,0,0,0,0,0,0},340 341 char_bmp_word[16]=342 {0x0000000,0x03FF0080,0x87FFFFFE,0x07FFFFFE,343 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,344 0,0,0,0,0,0,0,0},345 346 char_bmp_filename[16]=347 {0x0000000,0x03FF73FB,0xEFFFFFFF,0x6FFFFFFF,348 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,349 0,0,0,0,0,0,0,0},350 351 char_bmp_dec_numeric[16]=352 {0x0000000,0x03FF0000,0,0,0,0,0,0,0,0,0,0,0,0,0,0},353 354 char_bmp_hex_numeric[16]=355 {0x0000000,0x03FF0000,0x7E,0x7E,0,0,0,0,0,0,0,0,0,0,0,0},356 357 char_bmp_white_space[16]=358 {0x80002600,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},359 360 char_bmp_non_eol_white_space[16]=361 {0x80000200,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},362 363 char_bmp_zero_cr_nl_cursor[16]=364 {0x00002421,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},365 366 char_bmp_zero_tab_cr_nl_cursor[16]=367 {0x00002621,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},368 369 char_bmp_zero_tab_cr_nl_cursor_dollar[16]=370 {0x00002621,0x10,0,0,0,0,0,0,0,0,0,0,0,0,0,0},371 372 char_bmp_macro[16]=373 {0x80002600,0xFFFFFFDF,0xFFFFFFFF,0x7FFFFFFF,374 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,375 0,0,0,0,0,0,0,0},376 377 char_bmp_printable[16]=378 {0x80002600,0xFFFFFFFF,0xFFFFFFFF,0x7FFFFFFF,379 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,380 0,0,0,0,0,0,0,0},381 382 char_bmp_displayable[16]=383 {0x80000000,0xFFFFFFFF,0xFFFFFFFF,0x7FFFFFFF,384 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,385 0,0,0,0,0,0,0,0},386 387 char_bmp_safe_dollar[16]=388 {0x80000000,0xFFFFFFEF,0xFFFFFFFF,0x7FFFFFFF,389 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,390 0,0,0,0,0,0,0,0},//same but no dollar sign391 392 char_bmp_non_eol[16]=393 {0xFFFFDBFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,394 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,395 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,396 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};397 398U8 *LstSub(I64 sub, U8 *lst)399{//Point to lst entry.400//Not efficient. Use an array of U8 ptrs for efficiency.401 if (!lst) return NULL;402 while (*lst && sub>0) {403 while (*lst) //Advance to end of cur entry.404 lst++;405 lst++; //Skip trailing zero.406 if (*lst=='@') //Check for '@' alias lst entry.407 lst++;408 else409 sub--;410 }411 if (sub||!*lst)412 return NULL;413 else414 return lst;415}416 417I64 LstMatch(U8 *needle, U8 *haystack_lst,I64 flags=0)418{//-2 if Ambiguous419// -1 if not found420 // Not efficient. Use hash tables for efficiency.421 I64 n,sub=0,res=-1;422 U8 *ptr;423 Bool exact_match=FALSE;424 if (!haystack_lst) return -1;425 n=StrLen(needle);426 while (*haystack_lst) {427 if (*haystack_lst=='@') { //Check for '@' alias haystack_lst entry428 sub--;429 haystack_lst++;430 }431 ptr=needle;432 if (flags & LMF_IGNORE_CASE)433 while (*ptr && ToUpper(*ptr)==ToUpper(*haystack_lst)) {434 ptr++;435 haystack_lst++;436 }437 else438 while (*ptr && *ptr==*haystack_lst) {439 ptr++;440 haystack_lst++;441 }442 if (!*ptr) { //Did we reach end of needle?443 if (!*haystack_lst) //Did we reach end of haystack_lst?444 return sub; //Found Exact match445 else {446 if (res!=-1) {447 if (!exact_match)448 res=-2; //Ambiguous unless later exact match.449 } else {450 if (!(flags & LMF_EXACT))451 res=sub;452 }453 }454 }455 while (*haystack_lst) //Advance to end of cur entry.456 haystack_lst++;457 haystack_lst++; //Skip trailing zero458 sub++;459 }460 return res;461}462 463I64 StrOcc(U8 *src, I64 ch)464{//Count occurrences of a char.465 I64 i=0;466 if (!src) return 0;467 while (*src)468 if (*src++==ch)469 i++;470 return i;471}472 473I64 Spaces2Tabs(U8 *dst,U8 *src)474{//Src buf with spaces to dst buf without.475 U8 *src2;476 I64 chged=0,space_cnt,space_cnt2,col=0;477 if (*src)478 while (TRUE) {479 src2=src;480 while (*src2==CH_SPACE)481 src2++;482 space_cnt=src2-src;483 while (col+space_cnt>=8) {484 space_cnt2=8-col;485 if (space_cnt2==1)486 *dst++=CH_SPACE;487 else {488 *dst++='\t';489 chged+=space_cnt2-1;490 }491 space_cnt-=space_cnt2;492 col=0;493 }494 if (*src2=='\t') {495 if (space_cnt==1 && col==7)496 *dst++=CH_SPACE;497 else498 chged+=space_cnt;499 *dst++='\t';500 col=0;501 } else {502 while (space_cnt--) {503 *dst++=CH_SPACE;504 if (++col==8)505 col=0;506 }507 if (*src2) {508 *dst++=*src2;509 if (++col==8)510 col=0;511 } else512 break;513 }514 src=++src2;515 }516 *dst=0;517 return chged;518}519 520U8 *StrUtil(U8 *_src,I64 flags)521{//Modifies in place. See flags for all the options.522 U8 *src=_src,*dst=_src;523 I64 ch;524 525 if (flags & SUF_REM_LEADING)526 while (Bt(char_bmp_white_space,*src))527 src++;528 while (ch=*src++)529 if (Bt(char_bmp_white_space,ch)) {530 if (!(flags & SUF_REM_SPACES)) {531 if (flags & SUF_SINGLE_SPACE) {532 *dst++ = CH_SPACE;533 while ((ch=*src++) && Bt(char_bmp_white_space,ch));534 src--;535 } else536 *dst++ = ch;537 }538 } else if (!(flags & SUF_REM_CTRL_CHARS) || ch>=CH_SHIFT_SPACE)539 *dst++=ch;540 *dst=0;541 542 if (flags & SUF_REM_TRAILING)543 while (dst!=_src && (!*dst || Bt(char_bmp_white_space,*dst)))544 *dst-- =0;545 if (flags & SUF_TO_UPPER)546 for (dst=_src;*dst;dst++) {547 ch=*dst;548 if ('a'<=ch<='z')549 *dst=ch-0x20;550 }551 if (flags & SUF_TO_LOWER)552 for (dst=_src;*dst;dst++) {553 ch=*dst;554 if ('A'<=ch<='Z')555 *dst=ch+0x20;556 }557 if (flags & SUF_SAFE_DOLLAR)558 for (dst=_src;*dst;dst++) {559 ch=*dst;560 if (!Bt(char_bmp_safe_dollar,*dst))561 *dst='.';562 }563 if (flags & SUF_S2T)564 Spaces2Tabs(_src,_src);565 return _src;566}567 568U8 *StrFirstOcc(U8 *src,U8 *marker)569{//Point to 1st occurrence of marker set in str.570 I64 ch;571 while ((ch=*src++) && !StrOcc(marker,ch));572 if (ch)573 return src-1;574 else575 return NULL;576}577 578U8 *StrFirstRem(U8 *src,U8 *marker,U8 *dst=NULL)579{//Remove first str segment and place in dst buf or NULL.580 I64 ch;581 U8 *ptr=src,*res=dst;582 if (dst) {583 while ((ch=*ptr++) && !StrOcc(marker,ch))584 *dst++=ch;585 *dst=0;586 } else587 while ((ch=*ptr++) && !StrOcc(marker,ch));588 if (ch)589 StrCpy(src,ptr);590 else591 *src=0;592 return res;593}594 595U8 *StrLastOcc(U8 *src,U8 *marker)596{//Point to last occurrence of market set in str.597 I64 ch;598 U8 *res=NULL;599 while (ch=*src++)600 if (StrOcc(marker,ch))601 res=src-1;602 return res;603}604 605U8 *StrLastRem(U8 *src,U8 *marker,U8 *dst=NULL)606{//Remove last str segment and place in dst buf or NULL.607 U8 *ptr;608 if (ptr=StrLastOcc(src,marker)) {609 if (dst)610 StrCpy(dst,ptr+1);611 *ptr=0;612 } else {613 if (dst)614 StrCpy(dst,src);615 *src=0;616 }617 return dst;618}619 620U8 *StrFind(U8 *needle,U8 *haystack_str,I64 flags=0)621{//Find needle_str in haystack_str with options.622 Bool cont;623 U8 *saved_haystack_str=haystack_str;624 I64 plen=StrLen(needle);625 do {626 cont=FALSE;627 if (flags & SFF_IGNORE_CASE)628 haystack_str=StrIMatch(needle,haystack_str);629 else630 haystack_str=StrMatch(needle,haystack_str);631 if (haystack_str && flags & SFF_WHOLE_LABELS_BEFORE &&632 haystack_str!=saved_haystack_str &&633 Bt(char_bmp_alpha_numeric,*(haystack_str-1))) {634 haystack_str++;635 if (*haystack_str)636 cont=TRUE;637 else638 haystack_str=NULL;639 }640 if (haystack_str && flags & SFF_WHOLE_LABELS_AFTER &&641 Bt(char_bmp_alpha_numeric,*(haystack_str+plen))) {642 haystack_str++;643 if (*haystack_str)644 cont=TRUE;645 else646 haystack_str=NULL;647 }648 } while (cont);649 return haystack_str;650}651 652Bool WildMatch(U8 *test_str,U8 *wild_str)653{//Wildcard match with '*' and '?'.654 I64 ch1,ch2;655 U8 *fall_back_src=NULL,*fall_back_wild=NULL;656 while (TRUE) {657 if (!(ch1=*test_str++)) {658 if (*wild_str && *wild_str!='*')659 return FALSE;660 else661 return TRUE;662 } else {663 if (!(ch2=*wild_str++))664 return FALSE;665 else {666 if (ch2=='*') {667 fall_back_wild=wild_str-1;668 fall_back_src=test_str;669 if (!(ch2=*wild_str++))670 return TRUE;671 while (ch2!=ch1)672 if (!(ch1=*test_str++))673 return FALSE;674 } else675 if (ch2!='?' && ch1!=ch2) {676 if (fall_back_wild) {677 wild_str=fall_back_wild;678 test_str=fall_back_src;679 fall_back_wild=NULL;680 fall_back_src=NULL;681 } else682 return FALSE;683 }684 }685 }686 }687}688 