Code: Select all
SUB SSINCREMCORE (BYVAL VL32ADR AS UINT32, BYREF VR8POS AS UINT8)
'' Input: VL32ADR - address of the input string
'' VR8POS - position to increment, ZERO-based (1 to 255, not ZERO)
'' Output: - on success string incremented
'' - on failure VR8POS set to ZERO and string is trashed
'' - Works on a raw string (no size prefix, no ZERO termination)
'' - Doesn't care about string length (must be VR8POS < "length")
'' - Position VR8POS must be >= 1 (we never touch the ZERO'th character)
'' - Only numbers "0" to "9" and uppercase "A" to "Z" are incrementable,
'' lowercase letters and other junk are not
'' - ASM code uses only 3 registers EAX ECX EDX
DIAS UINT8 VL8POSI
VL8POSI=VR8POS
ASM
xor ecx, ecx '' MOVNTQ ECX,0
mov eax, [VL32ADR]
mov cl, [VL8POSI] '' May NOT be ZERO on entry !!!
test cl, cl '' CMPNTQ CL,0
jz jj5 '' Check for ZERO, no check for too high
add eax, ecx '' But we still need CL below !!!
jj0: mov dl, [eax] '' Pick
cmp dl, 48
jb jj1 '' NOT incrementable nor wrappable
cmp dl, 90
ja jj1 '' NOT incrementable nor wrappable
cmp dl, 64
ja jj2 '' Letter, OK, we can increment
cmp dl, 57
ja jj1 '' NOT incrementable nor wrappable
jj2: mov dh, 1 '' Pre-ASS'ume "evil" wrap
mov ch, 48
cmp dl, 57
je jj3 '' Hit "9", wrap to "0"
mov ch, 65
cmp dl, 90
je jj3 '' Hit "Z", wrap to "A"
inc dl '' Safe to increment
mov ch, dl
dec dh '' MOVNTQ DH,0 | OK, done, not "evil" wrap
jj3: mov [eax], ch '' POKE it back (incremented or wrapped)
test dh, dh '' CMPNTQ DH,0
jz jj5 '' Done !
jj1: dec cl
jz jj4 '' F**K !!! (don't touch ZERO'th character)
dec eax '' Safe to decrement
jmp jj0
'' -------
jj4: mov [VL8POSI], cl '' CL==0 | Failure | The string is trashed !!!
jj5:
END ASM
VR8POS=VL8POSI
END SUB '' SSINCREMCORE
Download now : http://users.freebasic-portal.de/dos386/incr.zip (19 KiB) (full code with test)
Problem: an application tries to save a file but the filename is already occupied by an existing file
Scenarios:
1. Miserably fail with an ENOENT - BAD :-(
2. Silently kick the existing file (examples: FBC and most other compilers, OBJCONV, old versions of NCONVERT, FFMPEG2THEORA) - BAD :-(
3. Ask the user whether to overwrite or not (example: FFMPEG) (but what then ???)
4. Auto-rename. This is what my code is about :-) You can try some conversion many 1000 times and the previous results are kept, so you can compare (except you specify a "very bad" name with no or few possible increments at start).
EDITED 2014-Feb-01