//----------------------------------------------------------- // // The string function library for 65CM. ( needs >= v0.070 ) // // It provides basic ( NULL terminated ) string handling // functions // // NB! Most of these functions depend on Memlib for memory // allocation. //----------------------------------------------------------- GOTO lib_skip_strfunc //----------------------------------------------------------- // strlen: Returns the string length of a null-terminated // string in memory. //----------------------------------------------------------- WORD lib_strlen_strptr //pointer to the string WORD lib_strlen_return //returns the length of the string //in bytes ( NULL not included ) LABEL lib_strlen WORD lib_strlen_intptr BYTE lib_strlen_bytval LET lib_strlen_intptr GET lib_strlen_strptr LET lib_strlen_return GET 0 PEEK lib_strlen_intptr GIVING lib_strlen_bytval WHILE lib_strlen_bytval INCREMENT lib_strlen_intptr INCREMENT lib_strlen_return PEEK lib_strlen_intptr GIVING lib_strlen_bytval WEND SUBEND //----------------------------------------------------------- // strcat: concatenates ("adds") the second null-terminated // string to the first and returns the address to // this third string //----------------------------------------------------------- WORD lib_strcat_str1ptr //pointer to the first string WORD lib_strcat_str2ptr //pointer to the second string WORD lib_strcat_return //pointer to the result LABEL lib_strcat WORD lib_strcat_spaceneed BYTE lib_strcat_bytval WORD lib_strcat_str3ptr // First of all, check if the operation is possible LET lib_strlen_strptr = lib_strcat_str1ptr GOSUB lib_strlen LET lib_strcat_spaceneed = lib_strlen_return LET lib_strlen_strptr = lib_strcat_str2ptr GOSUB lib_strlen ADD lib_strlen_return TO lib_strcat_spaceneed GIVING lib_strcat_spaceneed INCREMENT lib_strcat_spaceneed //make room for ending NULL // Try to allocate memory for the string LET lib_malloc_size = lib_strcat_spaceneed GOSUB lib_malloc LET lib_strcat_return = lib_malloc_return // If the space needed is less than the space available, exit and return NULL IF lib_strcat_return = NULL THEN GOTO lib_strcat_end ENDIF // Concatenate the strings and exit LET lib_strcat_str3ptr = lib_strcat_return PEEK lib_strcat_str1ptr GIVING lib_strcat_bytval WHILE lib_strcat_bytval POKE lib_strcat_str3ptr WITH lib_strcat_bytval INCREMENT lib_strcat_str3ptr INCREMENT lib_strcat_str1ptr PEEK lib_strcat_str1ptr GIVING lib_strcat_bytval WEND PEEK lib_strcat_str2ptr GIVING lib_strcat_bytval WHILE lib_strcat_bytval POKE lib_strcat_str3ptr WITH lib_strcat_bytval INCREMENT lib_strcat_str3ptr INCREMENT lib_strcat_str2ptr PEEK lib_strcat_str2ptr GIVING lib_strcat_bytval WEND POKE lib_strcat_str3ptr WITH 0 LABEL lib_strcat_end SUBEND //----------------------------------------------------------- // strcopy: Copy a string from another string, from position // to offset or end of string, and return a pointer // to the resulting string. //----------------------------------------------------------- WORD lib_strcopy_strptr WORD lib_strcopy_startpos // first char @ 0 WORD lib_strcopy_offset //how many chars to copy WORD lib_strcopy_return LABEL lib_strcopy WORD lib_strcopy_sourcelen WORD lib_strcopy_cutlen WORD lib_strcopy_posptr BYTE lib_strcopy_bytval WORD lib_strcopy_writepos // Check for stupid user mistakes (start position or offset // beyond string length) LET lib_strlen_strptr = lib_strcopy_strptr GOSUB lib_strlen LET lib_strcopy_sourcelen = lib_strlen_return IF lib_strcopy_sourcelen < lib_strcopy_startpos THEN LET lib_strcopy_return = NULL GOTO lib_strcopy_end ENDIF ADD lib_strcopy_startpos TO lib_strcopy_offset GIVING lib_strcopy_cutlen IF lib_strcopy_cutlen > lib_strcopy_sourcelen THEN SUBTRACT lib_strcopy_startpos FROM lib_strcopy_sourcelen GIVING lib_strcopy_offset ENDIF //Alloc mem copy copied string LET lib_malloc_size = lib_strcopy_offset INCREMENT lib_malloc_size GOSUB lib_malloc LET lib_strcopy_return = lib_malloc_return IF lib_strcopy_return = NULL THEN GOTO lib_strcopy_end ENDIF LET lib_strcopy_writepos = lib_strcopy_return // Execute copying ADD lib_strcopy_startpos TO lib_strcopy_strptr GIVING lib_strcopy_posptr ADD lib_strcopy_offset TO lib_strcopy_posptr GIVING lib_strcopy_cutlen PEEK lib_strcopy_posptr GIVING lib_strcopy_bytval WHILE lib_strcopy_posptr < lib_strcopy_cutlen POKE lib_strcopy_writepos WITH lib_strcopy_bytval INCREMENT lib_strcopy_writepos INCREMENT lib_strcopy_posptr PEEK lib_strcopy_posptr GIVING lib_strcopy_bytval WEND POKE lib_strcopy_writepos WITH NULL LABEL lib_strcopy_end SUBEND //----------------------------------------------------------- // strpos: Locate the position of one string in another. // Returns a pointer to the location of the // substring. //----------------------------------------------------------- WORD lib_strpos_strptr //The string to search in WORD lib_strpos_substrptr //The string to search for WORD lib_strpos_return LABEL lib_strpos LET lib_strpos_return = NULL WORD lib_strpos_strlen1 WORD lib_strpos_strlen2 LET lib_strlen_strptr = lib_strpos_strptr GOSUB lib_strlen LET lib_strpos_strlen1 = lib_strlen_return LET lib_strlen_strptr = lib_strpos_substrptr GOSUB lib_strlen LET lib_strpos_strlen2 = lib_strlen_return IF lib_strpos_strlen1 = 0 THEN SUBEND ENDIF IF lib_strpos_strlen2 = 0 THEN SUBEND ENDIF IF lib_strpos_strlen2 > lib_strpos_strlen1 THEN SUBEND ENDIF WORD lib_strpos_mainpos WORD lib_strpos_subpos WORD lib_strpos_mainlastpos BYTE lib_strpos_mainval BYTE lib_strpos_subval WORD lib_strpos_mainposfirstmatch BYTE lib_strpos_innerloop SUBTRACT lib_strpos_strlen2 FROM lib_strpos_strlen1 GIVING lib_strpos_mainlastpos ADD lib_strpos_strptr TO lib_strpos_mainlastpos GIVING lib_strpos_mainlastpos LET lib_strpos_mainpos = lib_strpos_strptr LET lib_strpos_subpos = lib_strpos_substrptr LET lib_strpos_innerloop = 0 PEEK lib_strpos_subpos GIVING lib_strpos_subval WHILE lib_strpos_mainpos <= lib_strpos_mainlastpos PEEK lib_strpos_mainpos GIVING lib_strpos_mainval IF lib_strpos_mainval = lib_strpos_subval THEN LET lib_strpos_mainposfirstmatch = lib_strpos_mainpos LET lib_strpos_innerloop = 1 ENDIF WHILE lib_strpos_mainval = lib_strpos_subval INCREMENT lib_strpos_mainpos INCREMENT lib_strpos_subpos PEEK lib_strpos_mainpos GIVING lib_strpos_mainval PEEK lib_strpos_subpos GIVING lib_strpos_subval IF lib_strpos_subval = 0 THEN //This is the match! We found substr! LET lib_strpos_return = lib_strpos_mainposfirstmatch SUBEND ENDIF WEND IF lib_strpos_innerloop <> 0 THEN LET lib_strpos_innerloop = 0 LET lib_strpos_mainpos = lib_strpos_mainposfirstmatch LET lib_strpos_subpos = lib_strpos_substrptr PEEK lib_strpos_subpos GIVING lib_strpos_subval ENDIF INCREMENT lib_strpos_mainpos WEND SUBEND //----------------------------------------------------------- // strcmp: Compares two strings. // Returns 2 if str1 is less than str2 // 1 if str1 is greater than str2 // 0 if they are equal. //----------------------------------------------------------- WORD lib_strcmp_str1 WORD lib_strcmp_str2 BYTE lib_strcmp_return LABEL lib_strcmp BYTE lib_strcmp_val1 BYTE lib_strcmp_val2 PEEK lib_strcmp_str1 GIVING lib_strcmp_val1 PEEK lib_strcmp_str2 GIVING lib_strcmp_val2 WHILE lib_strcmp_val1 = lib_strcmp_val2 INCREMENT lib_strcmp_str1 INCREMENT lib_strcmp_str2 PEEK lib_strcmp_str1 GIVING lib_strcmp_val1 PEEK lib_strcmp_str2 GIVING lib_strcmp_val2 IF lib_strcmp_val1 = 0 THEN GOTO lib_strcmp_loopexit ENDIF IF lib_strcmp_val2 = 0 THEN GOTO lib_strcmp_loopexit ENDIF WEND LABEL lib_strcmp_loopexit IF lib_strcmp_val1 = lib_strcmp_val2 THEN LET lib_strcmp_return GET 0 ENDIF IF lib_strcmp_val1 < lib_strcmp_val2 THEN LET lib_strcmp_return GET 2 ENDIF IF lib_strcmp_val1 > lib_strcmp_val2 THEN LET lib_strcmp_return GET 1 ENDIF SUBEND LABEL lib_skip_strfunc