//------------------------------------------------------------------------ // 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