397 lines
9.6 KiB
Text
397 lines
9.6 KiB
Text
//------------------------------------------------------------------------
|
|
// String library
|
|
//
|
|
// Author: Mattias Hansson
|
|
// Copyright (c) : 2005 Mattias Hansson
|
|
// License: GNU GPL 2
|
|
// Language: 65CM v0.4+
|
|
// Dependencies:
|
|
// ZP usage: $fb-$fe
|
|
//
|
|
// External functions:
|
|
// lib_string_strlen
|
|
// lib_string_strchr
|
|
// lib_string_strcpy
|
|
// lib_string_stpcpy
|
|
// lib_string_strncpy
|
|
// lib_string_strcmp
|
|
// lib_string_memset
|
|
// lib_string_strcat
|
|
// lib_string_strncat
|
|
|
|
//
|
|
// Internal function:
|
|
//
|
|
//
|
|
// Note: Several of the lib-functions are combined to save space, where
|
|
// this can be done at a fairly small speed penalty.
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
#IFNDEF __LIB_STRING
|
|
#DEFINE __LIB_STRING = 1
|
|
|
|
GOTO lib_string_skip
|
|
|
|
//Makes it possible for all modules that needs NULL
|
|
//to define the constant
|
|
#IFNDEF NULL
|
|
#DEFINE NULL = 0
|
|
#IFEND
|
|
|
|
WORD lib_string_strptr1 @ $fb
|
|
WORD lib_string_strptr2 @ $fd
|
|
WORD lib_string_length
|
|
|
|
//just aliases for the mem* functions
|
|
WORD lib_string_ptr1 @ $fb
|
|
WORD lib_string_ptr2 @ $fd
|
|
|
|
WORD lib_string_temp
|
|
|
|
|
|
//-----------------------------------------------------------
|
|
// lib_string_strlen
|
|
//
|
|
// Purpose: Returns the string length of a null-terminated
|
|
// string in memory.
|
|
//
|
|
// Params:
|
|
// lib_string_strptr1 - pointer to string to measure
|
|
// lib_string_length - returns the length of the string
|
|
//
|
|
// lib_string_strchr
|
|
//
|
|
// Purpose: Returns pointer to where char lib_string_sl_matchchar
|
|
// first occurs in string at lib_string_strptr1.
|
|
// Returns NULL if not found.
|
|
//-----------------------------------------------------------
|
|
|
|
BYTE lib_string_sl_matchchar
|
|
|
|
FUNC lib_string_strlen ( lib_string_strptr1 out:lib_string_length )
|
|
|
|
LET lib_string_sl_matchchar = 0
|
|
|
|
FUNC lib_string_strchr ( io:lib_string_strptr1 lib_string_sl_matchchar )
|
|
|
|
BYTE char
|
|
|
|
LET lib_string_length = 0
|
|
|
|
PEEK lib_string_strptr1 -> char
|
|
|
|
WHILE char
|
|
IF char == lib_string_sl_matchchar
|
|
SUBEND
|
|
ENDIF
|
|
INC lib_string_strptr1
|
|
INC lib_string_length
|
|
PEEK lib_string_strptr1 -> char
|
|
WEND
|
|
|
|
LET lib_string_strptr1 = NULL
|
|
FEND
|
|
|
|
|
|
//-----------------------------------------------------------
|
|
// lib_string_strcpy
|
|
//
|
|
// Purpose: Copies the null-terminated string at
|
|
// lib_string_strptr1 to lib_string_strptr2
|
|
//
|
|
// lib_string_stpcpy
|
|
//
|
|
// Purpose: Same as strcpy but returns a pointer to the
|
|
// end of the copy in lib_string_strptr2
|
|
//
|
|
// lib_string_strncpy
|
|
//
|
|
// Purpose: Copies the null-terminated string at
|
|
// lib_string_strptr1 to lib_string_strptr2, but
|
|
// stops after lib_string_length chars regardless
|
|
// of if the full string is copied
|
|
//
|
|
// Note: Dont send in 0 (zero) into lib_string_length.
|
|
//-----------------------------------------------------------
|
|
|
|
FUNC lib_string_stpcpy ( lib_string_strptr1 io:lib_string_strptr2 )
|
|
|
|
FUNC lib_string_strcpy ( lib_string_strptr1 lib_string_strptr2 )
|
|
|
|
LET lib_string_length = 0
|
|
|
|
FUNC lib_string_strncpy ( lib_string_strptr1 lib_string_strptr2 lib_string_length )
|
|
|
|
BYTE char
|
|
LET char = $ff
|
|
|
|
WHILE char
|
|
PEEK lib_string_strptr1 -> char
|
|
POKE lib_string_strptr2 , char
|
|
INC lib_string_strptr1
|
|
INC lib_string_strptr2
|
|
DEC lib_string_length
|
|
IF lib_string_length == 0
|
|
BREAK
|
|
ENDIF
|
|
WEND
|
|
|
|
FEND
|
|
|
|
//-----------------------------------------------------------
|
|
// lib_string_memset
|
|
//
|
|
// Purpose: Sets lib_string_length bytes starting at
|
|
// lib_string_ptr1 to the value lib_string_memset_value
|
|
//
|
|
//-----------------------------------------------------------
|
|
|
|
BYTE lib_string_memset_value
|
|
FUNC lib_string_memset ( lib_string_ptr1 lib_string_memset_value lib_string_length )
|
|
|
|
ADD lib_string_ptr1 + lib_string_length -> lib_string_ptr2
|
|
DEC lib_string_ptr2
|
|
WHILE lib_string_ptr2 >= lib_string_ptr1
|
|
POKE lib_string_ptr2 , lib_string_memset_value
|
|
DEC lib_string_ptr2
|
|
WEND
|
|
|
|
FEND
|
|
|
|
//-----------------------------------------------------------
|
|
// lib_string_strcmp
|
|
//
|
|
// purpose: Compare two strings.
|
|
// Returns 2 if str1 is less than str2
|
|
// 1 if str1 is greater than str2
|
|
// 0 if they are equal.
|
|
//-----------------------------------------------------------
|
|
|
|
BYTE lib_string_strcmp_result
|
|
|
|
FUNC lib_string_strcmp ( lib_string_strptr1 lib_string_strptr2 out:lib_string_strcmp_result )
|
|
BYTE val1
|
|
BYTE val2
|
|
|
|
LET lib_string_strcmp_result = 0
|
|
|
|
PEEK lib_string_strptr1 -> val1
|
|
PEEK lib_string_strptr2 -> val2
|
|
|
|
WHILE val1 == val2
|
|
INC lib_string_strptr1
|
|
INC lib_string_strptr2
|
|
PEEK lib_string_strptr1 -> val1
|
|
PEEK lib_string_strptr2 -> val2
|
|
IF val1 == 0
|
|
BREAK
|
|
ENDIF
|
|
IF val2 == 0
|
|
BREAK
|
|
ENDIF
|
|
WEND
|
|
|
|
IF val1 < val2
|
|
LET lib_string_strcmp_result = 2
|
|
ENDIF
|
|
|
|
IF val1 > val2
|
|
LET lib_string_strcmp_result = 1
|
|
ENDIF
|
|
|
|
FEND
|
|
|
|
//-----------------------------------------------------------
|
|
// lib_string_strstr
|
|
//
|
|
// purpose:
|
|
// Locate the position of one string in another.
|
|
// Returns a pointer to the location of the
|
|
// substring. (or NULL if not found)
|
|
//-----------------------------------------------------------
|
|
|
|
WORD lib_string_strstr_return
|
|
|
|
FUNC lib_string_strstr ( lib_string_strptr1 lib_string_strptr2 out:lib_string_strstr_return )
|
|
|
|
LET lib_string_strstr_return = NULL
|
|
WORD strlen1
|
|
WORD strlen2
|
|
WORD substartpos
|
|
WORD mainlastpos
|
|
BYTE mainval
|
|
BYTE subval
|
|
WORD strptr1firstmatch
|
|
BYTE innerloop
|
|
|
|
//Ugly hack: Since "lib_string_strptr1" is used internally in strlen we remember the value in a temp variable
|
|
LET lib_string_temp = lib_string_strptr1
|
|
CALL lib_string_strlen ( lib_string_strptr1 strlen1 )
|
|
CALL lib_string_strlen ( lib_string_strptr2 strlen2 )
|
|
//Ugly hack: Since "lib_string_strptr1" is used internally in strlen we restore the value from a temp variable
|
|
LET lib_string_strptr1 = lib_string_temp
|
|
|
|
IF strlen1 == 0
|
|
SUBEND
|
|
ENDIF
|
|
IF strlen2 == 0
|
|
SUBEND
|
|
ENDIF
|
|
|
|
IF strlen2 > strlen1
|
|
SUBEND
|
|
ENDIF
|
|
|
|
SUBT strlen1 - strlen2 -> mainlastpos
|
|
ADD lib_string_strptr1 + mainlastpos -> mainlastpos
|
|
|
|
LET substartpos = lib_string_strptr2
|
|
LET innerloop = 0
|
|
PEEK lib_string_strptr2 -> subval
|
|
|
|
WHILE lib_string_strptr1 <= mainlastpos
|
|
PEEK lib_string_strptr1 -> mainval
|
|
IF mainval = subval
|
|
LET strptr1firstmatch = lib_string_strptr1
|
|
LET innerloop = 1
|
|
ENDIF
|
|
WHILE mainval = subval
|
|
INC lib_string_strptr1
|
|
INC lib_string_strptr2
|
|
PEEK lib_string_strptr1 -> mainval
|
|
PEEK lib_string_strptr2 -> subval
|
|
IF subval = 0
|
|
//This is the match! We found substr!
|
|
LET lib_string_strstr_return = strptr1firstmatch
|
|
SUBEND
|
|
ENDIF
|
|
WEND
|
|
IF innerloop != 0
|
|
LET innerloop = 0
|
|
LET lib_string_strptr1 = strptr1firstmatch
|
|
LET lib_string_strptr2 = substartpos
|
|
PEEK lib_string_strptr2 -> subval
|
|
ENDIF
|
|
INC lib_string_strptr1
|
|
WEND
|
|
|
|
FEND
|
|
|
|
//-----------------------------------------------------------
|
|
// lib_string_strcat
|
|
//
|
|
// purpose:
|
|
// To concatenate two strings.
|
|
// Appends lib_string_strptr1 to the
|
|
// end of lib_string_strptr2 (overwritng
|
|
// the terminating NULL character).
|
|
//
|
|
// lib_string_strncat
|
|
//
|
|
// purpose:
|
|
// very similar to strcat except at most
|
|
// lib_string_sc_copymaxchars are
|
|
// copied from the source. result is
|
|
// always NULL-terminated.
|
|
// (i.e. result string is at most
|
|
// length( lib_string_strptr1 ) +
|
|
// lib_string_sc_copymaxchars + 1
|
|
//
|
|
// Note:
|
|
// Be sure that memory after NULL
|
|
// in lib_string_strptr2 is avaliable
|
|
// for writing (so you don't overwrite
|
|
// something else lying there, or you
|
|
// may get some very unexpected
|
|
// results.
|
|
//-----------------------------------------------------------
|
|
|
|
WORD lib_string_sc_copymaxchars
|
|
|
|
FUNC lib_string_strcat ( lib_string_strptr1 lib_string_strptr2 )
|
|
|
|
LET lib_string_sc_copymaxchars = $ffff
|
|
|
|
FUNC lib_string_strncat ( lib_string_strptr1 lib_string_strptr2 lib_string_sc_copymaxchars )
|
|
|
|
BYTE char
|
|
|
|
//first find end of string2
|
|
PEEK lib_string_strptr2 -> char
|
|
WHILE char
|
|
INC lib_string_strptr2
|
|
PEEK lib_string_strptr2 -> char
|
|
WEND
|
|
|
|
PEEK lib_string_strptr1 -> char
|
|
POKE lib_string_strptr2 , char
|
|
WHILE char
|
|
PEEK lib_string_strptr1 -> char
|
|
POKE lib_string_strptr2 , char
|
|
INC lib_string_strptr1
|
|
INC lib_string_strptr2
|
|
DEC lib_string_sc_copymaxchars
|
|
IF lib_string_sc_copymaxchars == 0
|
|
POKE lib_string_strptr2 , 0
|
|
SUBEND
|
|
ENDIF
|
|
WEND
|
|
|
|
FEND
|
|
|
|
//-----------------------------------------------------------
|
|
// lib_string_memcmp
|
|
//
|
|
// Purpose:
|
|
// Compare two memory areas.
|
|
//
|
|
//-----------------------------------------------------------
|
|
|
|
BYTE lib_string_mc_res
|
|
|
|
FUNC lib_string_memcmp ( lib_string_ptr1 lib_string_ptr2 lib_string_length out:lib_string_mc_res )
|
|
|
|
BYTE b1
|
|
BYTE b2
|
|
|
|
LET lib_string_mc_res = 1
|
|
WHILE lib_string_length
|
|
PEEK lib_string_ptr1 -> b1
|
|
PEEK lib_string_ptr2 -> b2
|
|
IF b1 != b2
|
|
SUBEND
|
|
ENDIF
|
|
INC lib_string_ptr1
|
|
INC lib_string_ptr2
|
|
DEC lib_string_length
|
|
WEND
|
|
|
|
LET lib_string_mc_res = 0
|
|
FEND
|
|
|
|
|
|
//-----------------------------------------------------------
|
|
// lib_string_memcpy
|
|
//
|
|
// Purpose:
|
|
// Copy contants of a memory area to another memory area
|
|
//-----------------------------------------------------------
|
|
|
|
FUNC lib_string_memcpy ( lib_string_ptr1 lib_string_ptr2 lib_string_length )
|
|
|
|
BYTE btemp
|
|
|
|
WHILE lib_string_length
|
|
PEEK lib_string_ptr1 -> btemp
|
|
POKE lib_string_ptr2 , btemp
|
|
INC lib_string_ptr1
|
|
INC lib_string_ptr2
|
|
DEC lib_string_length
|
|
WEND
|
|
FEND
|
|
|
|
|
|
LABEL lib_string_skip
|
|
|
|
#IFEND
|