Hello,
Title case convertion with Poasm :
include TitleCase.inc
.data
LookupTable1 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
db 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
db 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
LookupTable2 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
sample db 'WHAT/A[CRAZY]{NIGHT}(OF)<PROGRAMMING>?IT~WAS!',0
.code
TitleCase PROC uses esi edi ebx string:DWORD
mov ecx,1
mov esi,OFFSET LookupTable1
mov edx,OFFSET LookupTable2
mov ebx,ecx
mov edi,string
sub edi,ebx
@@:
add edi,ecx
movzx eax,BYTE PTR [edi]
test eax,eax
jz finish
cmp BYTE PTR [esi+eax],cl
jne CheckTable2
mov ebx,1
jmp @b
CheckTable2:
cmp BYTE PTR [edx+eax],cl
jne @b
or eax,32
mov BYTE PTR [edi],al
cmp ebx,ecx
jne @b
sub eax,32
mov BYTE PTR [edi],al
xor ebx,ebx
jmp @b
finish:
ret
TitleCase ENDP
start:
invoke TitleCase,ADDR sample
invoke printf,ADDR sample
invoke ExitProcess,0
END start
Nice example, Erol :thumbsup:
There are diverging views on the rules of "titlecasing":
TitleCase proc The Catcher In The Rye, Pride And Prejudice, Clockwork Orange Are Famous
MB TitleCase$ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1536) The Catcher in the Rye, Pride and Prejudice, Clockwork Orange are Famous
titlecase.com (http://www.titlecase.com/) The Catcher in the Rye, Pride and Prejudice, Clockwork Orange Are Famous
titlecaseconverter (https://titlecaseconverter.com/) The Catcher in the Rye, Pride and Prejudice, Clockwork Orange Are Famous
convertcase.net (https://convertcase.net/title-case-converter/) The Catcher in the Rye, Pride and Prejudice, Clockwork Orange Are Famous
I am actually a bit surprised that "are" is being capitalised by the online tools. I may have to adapt my own TitleCase$...
Hi Erol
When I looked at the code, I noticed that the characters of the two tables do not overlap.
This means that you can create only one table to save some memory.
Biterider
Nice example. But I don't think this is particular to Poasm, is it? Looks like it should work with any assembler.
Quote from: jj2007 on December 29, 2023, 08:29:20 AMThere are diverging views on the rules of "titlecasing":
MB TitleCase$ (https://www.jj2007.eu/MasmBasicQuickReference.htm#Mb1536) The Catcher in the Rye, Pride and Prejudice, Clockwork Orange are Famous
JJ, your case assignment is the classically correct one, according to English usage consensus (e.g., Strunk & White's
The Elements of Style). Articles and prepositions aren't capitalized. (Although "famous" shouldn't be capitalized unless it's actually part of a title.)
Hi Vortex
Here is a code variant with a combined table :cool:
align ALIGN_DATA
.const
TITLE_CASE_TABLE label BYTE
; NUL SOH STX ETX EDT ENQ ACK BEL BS TAB LF VF FF CR SO SI
db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
; DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN BM SUB ESC FS GS RS US
db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
; SPC ! " # $ % & ' ( ) * + , - . /
db 004,004,004,004,004,004,004,004,004,004,004,004,004,004,004,004 ;+,/
; 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
db 000,000,000,000,000,000,000,000,000,000,004,004,004,004,004,004 ;0..9
; @ A B C D E F G H I J K L M N O
db 004,001,001,001,001,001,001,001,001,001,001,001,001,001,001,001 ;A..O
; P Q R S T U V W X Y Z [ \ ] ^ _
db 001,001,001,001,001,001,001,001,001,001,001,004,004,004,004,004 ;P..Z
; ` a b c d e f g h i j k l m n o
db 004,002,002,002,002,002,002,002,002,002,002,002,002,002,002,002 ;a..o
; p q r s t u v w x y z { | } ~
db 002,002,002,002,002,002,002,002,002,002,002,004,004,004,004,000 ;p..z
db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
The 32 bit code for ANSI strings is
TC_IS_UPPER equ 1
TC_IS_LOWER equ 2
TC_IS_SEPAR equ 4
TC_NEED_UPPER equ 1
TC_NEED_LOWER equ 2
.code
OPTION PROC:NONE
align ALIGN_CODE
TitleCase proc pString:POINTER
mov ecx, [esp + 4]
mov al, TC_NEED_UPPER ;Always start with TC_NEED_UPPER
.repeat
movzx edx, BYTE ptr [ecx]
.break .if edx == 0
mov ah, BYTE ptr [TITLE_CASE_TABLE + edx]
.if al == TC_NEED_UPPER
.if (ah & TC_IS_LOWER)
sub edx, 32
.endif
.if !(ah & TC_IS_SEPAR)
mov al, TC_NEED_LOWER
.endif
.else
.if (ah & TC_IS_UPPER)
add edx, 32
.endif
.if (ah & TC_IS_SEPAR)
mov al, TC_NEED_UPPER
.endif
.endif
mov BYTE ptr [xcx], dl ;Store the result
add ecx, sizeof BYTE
.until FALSE
ret 4
TitleCase endp
OPTION PROC:DEFAULT
Attached to complete source.
Biterider