#include #include #include #include #include #include #include #ifdef MAP_EDITOR2 #include "../map_editor2/global.h" #else #include "global.h" #endif #include "md5.h" /* NOTE: This file contains implementations of the following, currently unused and commented functions: * Look at the end of the file. * * Sint32 get_string_after_string(const Uint8*, const Uint8*, Sint32, Uint*, int); */ #ifndef LINUX int my_UTF8Toisolat1(char **dest, size_t * lu, const char **src, size_t * len); #else int my_UTF8Toisolat1(char **dest, size_t * lu, char **src, size_t * len); #endif // find the first occurance of needle in haystack, and return the distance to // that string. If beggining is 1, it returns the offset to the beginning of // the string otherwise it returns the offset to the end of the string. Needle // must be null-terminated. hyastack need not be, but must be at least max_len // bytes long Sint32 get_string_occurance (const char* needle, const char* haystack, const Uint32 max_len, const char beginning) { const Uint32 n_len = strlen(needle); Uint32 istart, i; Uint32 search_len; if (max_len < n_len) { return -1; } for (istart = 0, search_len = max_len - n_len; istart <= search_len; istart++) { for (i = 0; i < n_len; i++) { if (tolower(haystack[istart+i]) != tolower(needle[i])) { break; } } if (i >= n_len) { // We found the string. return the beginning if asked if (beginning) { return istart; } // return the end of the string occurence, but skip // space and equal signs while ((istart+i < max_len) && (haystack[istart+i] == ' ' || haystack[istart+i] == '=')) { i++; } return istart+i; } } return -1; } // This function returns an integer, after the needle in the haystack // string. If the string is not found, after max_len, the function returns -1. // The function is NOT case sensitive Sint32 get_integer_after_string (const char *needle, const char *haystack, Uint32 max_len) { Sint32 n_end = get_string_occurance (needle, haystack, max_len, 0); Uint32 istart; if (n_end < 0) { // needle not found return -1; } istart = n_end; while (istart < max_len) { if (haystack[istart] == '\n') // no integer on this line return -1; if (isdigit (haystack[istart]) || haystack[istart] == '+' || haystack[istart] == '-') // we've probably found a number return atoi (&haystack[istart]); istart++; } // no integer after needle return -1; } // This function returns a float, after the source string in the destination // string. If the string is not found, after max_len, the function returns // -1.0f. The function is NOT case sensitive float get_float_after_string (const char *needle, const char *haystack, Uint32 max_len) { Sint32 n_end = get_string_occurance (needle, haystack, max_len, 0); Uint32 istart; if (n_end < 0) { // needle not found return -1.0f; } istart = n_end; while (istart < max_len) { if (haystack[istart] == '\n') // no number on this line return -1.0f; if (isdigit (haystack[istart]) || haystack[istart] == '+' || haystack[istart] == '-' || haystack[istart] == '.') // we've probably found a number return atof (&haystack[istart]); istart++; } // no number after needle return -1.0f; } char* safe_strncpy(char *dest, const char * source, const size_t len) { if (len > 0) { strncpy(dest, source, len - 1); dest[len - 1] = '\0'; } return dest; } char* safe_strncpy2(char *dest, const char * source, const size_t dest_len, const size_t src_len) { if (dest_len > 0) { if (src_len >= dest_len) { strncpy(dest, source, dest_len - 1); dest[dest_len - 1] = '\0'; } else { strncpy(dest, source, src_len); dest[src_len] = '\0'; } } return dest; } int safe_snprintf(char *dest, const size_t len, const char* format, ...) { int ret; if (len > 0) { va_list ap; va_start(ap, format); #ifdef __MINGW32__ ret = vsnprintf(dest, len, format, ap); #else #if defined(WINDOWS) && (defined(__MINGW32__) || defined(_MSC_VER)) ret = _vsnprintf(dest, len, format, ap); #else ret = vsnprintf(dest, len, format, ap); #endif #endif va_end(ap); dest[len - 1] = '\0'; if ((ret < 0) || (ret >= len)) return len; return ret; } return 0; } void my_strcp(char *dest,const char * source) { while(*source) { *dest++=*source++; } *dest='\0'; } void my_strncp (char *dest, const char *source, size_t len) { while (*source != '\0' && --len > 0) { *dest++ = *source++; } *dest = '\0'; } void my_strcat(char *dest,const char * source) { int i,l,dl; l=strlen(source); dl=strlen(dest); for(i=0;i=65 && ch1<=90)ch1+=32;//make lowercase if(ch2>=65 && ch2<=90)ch2+=32;//make lowercase if(ch1!=ch2)break; } if(i!=len)return 0; else return 1; } Sint32 my_strcompare(const char *dest, const char *src) { Uint32 len; len=strlen(dest); if(len!=strlen(src))return 0; return(my_strncompare(dest, src, len)); } // is this string more then one character and all alpha in it are CAPS? Sint32 my_isupper(const char *src, int len) { int alpha=0; if (len < 0) len=strlen(src); if(!src || !src[0] || !src[1] || !src[2] || len == 0) return 0; while(*src && len > 0) { if(isalpha(*src)) alpha++; if((isdigit(*src)&&alpha= chars_per_line){//Wrap it //go back to the last space while(i){ if(str[i]=='/' || str[i]=='-' || str[i]=='?' || str[i]=='!' || str[i]==' ' || str[i]=='\n' || str[i]=='\r') break; i--; } if(i){ i++; if(str[i]==' ')str++; } else { //Force a break then... i=chars_per_line; } } str+=i; cur[i]=0; } if(my_str)my_str[lines]=NULL;//Used to get the bounds for displaying each line } return my_str; } // File utilities Uint32 clean_file_name (char *dest, const char *src, Uint32 max_len) { Uint32 len; Uint32 i; len = strlen (src); if (len >= max_len) len = max_len-1; for (i = 0; i < len; i++) { if (src[i] == '\\') dest[i] = '/'; else dest[i] = src[i]; } // always place a null at the end dest[len] = '\0'; return len; } /*XML*/ float xmlGetFloat(xmlNode * n, xmlChar * c) { char * t=(char*)xmlGetProp(n,c); float f=t?atof(t):0.0f; xmlFree(t); return f; } int xmlGetInt(xmlNode *n, xmlChar *c) { char *t=(char*)xmlGetProp(n,c); int i=t?atoi(t):0; xmlFree(t); return i; } int my_xmlStrncopy(char ** out, const char * in, int len) { if(in) { size_t lin=0; size_t lout=0; int l1=0; int l2=0; int retval=1; char *inbuf; char *inbuf2; char *outbuf; char *outbuf2; lin=strlen(in); l2=xmlUTF8Strlen((xmlChar*)in); if(l2<0) lout=l1; else if (len>0 && len 0) { MD5Digest(&md5, buffer, length); } MD5Close(&md5, digest); fclose(fp); } /* currently UNUSED //find & copy a string into memory //return the length or -1 if not found Sint32 get_string_after_string(const Uint8 * source_pointer, const Uint8 * dest_pointer, Sint32 max_len, Uint8 *value, Sint32 value_len) { int i; int loc=get_string_occurance(source_pointer, dest_pointer, max_len, 0); if (loc < 0) { return -1; } // now copy the string for(i=0;i 0 ){ str[size-1] = '\0'; } if (ret < 0 || ret >= size) { return size; } return ret; } #endif int find_description_index (const dict_elem dict[], const char *elem, const char *desc) { int idx = 0; char *key; while ((key = dict[idx].desc) != NULL) { if (strcasecmp (key, elem) == 0) return dict[idx].index; idx++; } LOG_ERROR("Unknown %s \"%s\"\n", desc, elem); return -1; } void get_string_value (char *buf, size_t maxlen, xmlNode *node) { if (node->children == NULL) buf[0] = '\0'; else my_strncp (buf, (char*)node->children->content, maxlen); } void get_item_string_value (char *buf, size_t maxlen, xmlNode *item, const unsigned char *name) { xmlNode *node; // look for this entry in the children for(node=item->children; node; node=node->next){ if(node->type == XML_ELEMENT_NODE) { if(xmlStrcasecmp(node->name, name) == 0){ if (node->children == NULL) buf[0] = '\0'; else my_strncp (buf, (char*)node->children->content, maxlen); return; } } } } int get_bool_value (xmlNode *node) { Uint8 *tval; if (node->children == NULL) return 0; tval = node->children->content; return (xmlStrcasecmp (tval, (Uint8 *)"yes") == 0 || xmlStrcasecmp (tval, (Uint8 *)"true") == 0 || xmlStrcasecmp (tval, (Uint8 *)"1") == 0); } double get_float_value (xmlNode *node) { if (node->children == NULL) return 0.0; return atof ((char*)node->children->content); } int get_int_property (xmlNode *node, const char *prop) { xmlAttr *attr; for (attr = node->properties; attr; attr = attr->next) { if (attr->type == XML_ATTRIBUTE_NODE && xmlStrcasecmp (attr->name, (Uint8 *)prop) == 0) { return atoi ((char*)attr->children->content); } } return -1; } int get_property (xmlNode *node, const char *prop, const char *desc, const dict_elem dict[]) { xmlAttr *attr; for (attr = node->properties; attr; attr = attr->next) { if (attr->type == XML_ATTRIBUTE_NODE && xmlStrcasecmp (attr->name, (Uint8 *)prop) == 0) { return find_description_index (dict, (char*)attr->children->content, desc); } } LOG_ERROR("Unable to find property %s in node %s\n", prop, node->name); return -1; } char *get_string_property (xmlNode *node, const char *prop) { xmlAttr *attr; for (attr = node->properties; attr; attr = attr->next) { if (attr->type == XML_ATTRIBUTE_NODE && xmlStrcasecmp (attr->name, (Uint8 *)prop) == 0) { return (char*)attr->children->content; } } #ifdef DEBUG // don't normally report this, or optional properties will report errors LOG_ERROR("Unable to find property %s in node %s\n", prop, node->name); #endif //DEBUG return ""; }