| /* | |
| * GraphApp - Cross-Platform Graphics Programming Library. | |
| * | |
| * File: strings.c -- local string functions. | |
| * Platform: Windows Version: 2.44 Date: 1998/09/09 | |
| * | |
| * Version: 1.00 Changes: Original version by Lachlan Patrick. | |
| * Version: 2.00 Changes: Added del_string. | |
| * Version: 2.30 Changes: Now uses array(), not malloc(). | |
| * Version: 2.44 Changes: Now uses array() instead of static char[]. | |
| */ | |
| /* Copyright (C) 1993-1998 Lachlan Patrick | |
| This file is part of GraphApp, a cross-platform C graphics library. | |
| GraphApp is free software; you can redistribute it and/or modify it | |
| under the terms of the GNU Library General Public License. | |
| GraphApp is distributed in the hope that it will be useful, but | |
| WITHOUT ANY WARRANTY. | |
| See the file COPYLIB.TXT for details. | |
| */ | |
| #include "internal.h" | |
| /* | |
| * Create and return a newly allocated copy of a string. | |
| * Null strings are converted into empty strings first. | |
| */ | |
| char *new_string(const char *src) | |
| { | |
| char *str; | |
| if (! src) | |
| src = ""; | |
| str = array (string_length(src), char); | |
| if (str) | |
| copy_string(str, src); | |
| return str; | |
| } | |
| void del_string(const char *str) | |
| { | |
| discard(str); | |
| } | |
| /* | |
| * String length function. | |
| * If the string is null, the length is defined to be zero. | |
| */ | |
| long string_length(const char *s) | |
| { | |
| long len = 0; | |
| if (s) | |
| while (s[len]) | |
| len++; | |
| return len; | |
| } | |
| /* | |
| * Copy a string. | |
| * Same as strcpy except it avoids doing anything to null strings. | |
| */ | |
| void copy_string(char *dest, const char *src) | |
| { | |
| int len; | |
| if ((dest) && (src)) { | |
| for (len=0; src[len]; len++) | |
| dest[len] = src[len]; | |
| dest[len] = '\0'; | |
| } | |
| } | |
| /* | |
| * String comparison function. | |
| * Null == null, null == "", "" == null, otherwise same as strcmp. | |
| */ | |
| int compare_strings(const char *s1, const char *s2) | |
| { | |
| int len, diff; | |
| if (s1 == s2) | |
| return 0; | |
| else if (s1 == NULL) { /* s2 cannot be null since s1 != s2 */ | |
| if (s2[0] == '\0') | |
| return 0; | |
| return -1; | |
| } | |
| else if (s2 == NULL) { /* s1 is not null */ | |
| if (s1[0] == '\0') | |
| return 0; | |
| return +1; | |
| } | |
| else { | |
| for (len=0; s1[len] || s2[len]; len++) { | |
| diff = s1[len] - s2[len]; | |
| if (diff) | |
| return diff; | |
| } | |
| return 0; | |
| } | |
| } | |
| /* | |
| * Append one string to another, and return the result. | |
| * This function correctly handles the situation where one or both | |
| * of the parameters are temporary strings returned by an earlier | |
| * call to this function. | |
| */ | |
| const char *add_strings(const char *s1, const char *s2) | |
| { | |
| static char *buffer = NULL; | |
| char *prev; | |
| int len1, len2; | |
| prev = buffer; | |
| if (! s1) | |
| return s2; | |
| else if (! s2) | |
| return s1; | |
| len1 = string_length(s1); | |
| len2 = string_length(s2); | |
| buffer = array (len1+len2, char); | |
| if (buffer != NULL) { | |
| copy_string(buffer, s1); | |
| copy_string(buffer+len1, s2); | |
| } | |
| if (prev) | |
| discard(prev); /* free previous string buffer */ | |
| return buffer; | |
| } | |
| /* | |
| * Convert a char to a string, return the result in a static buffer. | |
| */ | |
| char *char_to_string(const char ch) | |
| { | |
| static char str[2]; | |
| str[0] = ch; | |
| str[1] = '\0'; | |
| return str; | |
| } | |
| /* | |
| * Convert an integer to a string, return the result in a static buffer. | |
| */ | |
| char *int_to_string(long i) | |
| { | |
| static char *str = NULL; | |
| if (str == NULL) | |
| str = array(40,char); | |
| sprintf(str, "%ld", i); | |
| return str; | |
| } | |
| /* | |
| * Convert a floating point number to a string, | |
| * return the result in a static buffer. | |
| */ | |
| char *float_to_string(float f) | |
| { | |
| static char *str = NULL; | |
| if (str == NULL) | |
| str = array(40,char); | |
| sprintf(str, "%g", f); | |
| return str; | |
| } | |
| /* | |
| * Case-insensitive string comparison function. | |
| */ | |
| PROTECTED | |
| int string_diff(const char *s, const char *t) | |
| { | |
| int ch1, ch2; | |
| int diff = 0; | |
| while ((diff == 0) && ((*s != '\0') || (*t != '\0'))) | |
| { | |
| ch1 = *s; ch2 = *t; | |
| if ((ch1 >= 'A') && (ch1 <= 'Z')) | |
| ch1 = ch1 - 'A' + 'a'; | |
| if ((ch2 >= 'A') && (ch2 <= 'Z')) | |
| ch2 = ch2 - 'A' + 'a'; | |
| diff = (ch1 - ch2); | |
| s++; t++; | |
| } | |
| return diff; | |
| } | |
| /* | |
| * Produce a new string which has CR-LF instead of just '\n' | |
| * to mark end of line. The returned string must later be freed. | |
| */ | |
| PROTECTED | |
| char *to_dos_string(const char *text) | |
| { | |
| const char *s; | |
| char *newstr, *ss; | |
| char prev; | |
| long length = 0; | |
| if (!text) | |
| return (char *) NULL; | |
| prev = '\0'; | |
| for (s = text; *s != '\0'; s++) { | |
| length++; | |
| if ((*s == '\n') && (prev != '\r')) | |
| length++; | |
| prev = *s; | |
| } | |
| newstr = array (length, char); | |
| prev = '\0'; | |
| for (ss = newstr; *text != '\0'; ss++, text++) { | |
| if ((*text == '\n') && (prev != '\r')) { | |
| *ss = '\r'; | |
| ss++; | |
| } | |
| *ss = *text; | |
| prev = *ss; | |
| } | |
| *ss = '\0'; | |
| return newstr; | |
| } | |
| /* | |
| * Strip carriage returns from a string. The resulting | |
| * string must later be freed. | |
| */ | |
| PROTECTED | |
| char *to_c_string(const char *text) | |
| { | |
| const char *s; | |
| char *newstr, *ss; | |
| long length = 0; | |
| if (!text) | |
| return (char *) NULL; | |
| for (s = text; *s != '\0'; s++) { | |
| length++; | |
| if ((*s == '\r') && (*(s+1) == '\n')) | |
| length--; | |
| } | |
| newstr = array (length, char); | |
| for (ss = newstr; *text != '\0'; ss++, text++) { | |
| if ((*text == '\r') && (*(text+1) == '\n')) | |
| text++; | |
| *ss = *text; | |
| } | |
| *ss = '\0'; | |
| return newstr; | |
| } |