NMD
|
00001 #include <stdlib.h> 00002 #include "nmd.h" 00003 #include "nmd_impl.h" 00004 #include "string.h" 00005 00006 /*! \page string NMD String Library 00007 00008 We have some routines for string handling. 00009 */ 00010 struct NMD_string_ { 00011 int cookie; 00012 int n; char *t; 00013 }; 00014 00015 #undef __FUNCT__ 00016 #define __FUNCT__ "NMDStringCreateOfSize" 00017 /*! 00018 Internal auxiliary function for creating a string object of a given length. 00019 Zero length is allowed. 00020 */ 00021 static NMDErrorCode NMDStringCreateOfSize(int n,NMD_string *r_str) 00022 { 00023 NMD_string str; char *t; 00024 NMD_MALLOC(t,n+1,char,"nmd string"); 00025 NMD_MALLOC(str,1,struct NMD_string_,"string object"); 00026 str->n = n; str->t = t; str->cookie = NMDCOOKIE; 00027 *r_str = str; 00028 return 0; 00029 } 00030 00031 #undef __FUNCT__ 00032 #define __FUNCT__ "NMDStringCreate" 00033 /*! Create a string object around a C string; the C string is copied, 00034 so it can be freed by the calling environment. 00035 */ 00036 NMDErrorCode NMDStringCreate(const char *txt,NMD_string *r_str) 00037 { 00038 NMD_string str; NMDErrorCode ierr; int l; 00039 l = strlen(txt); 00040 ierr = NMDStringCreateOfSize(l,&str); NMD_ERR_RETURN(ierr); 00041 if (l) memcpy(str->t,txt,l); 00042 *r_str = str; 00043 return 0; 00044 } 00045 00046 #undef __FUNCT__ 00047 #define __FUNCT__ "NMDStringDestroy" 00048 /*! Destroy a string object, and free the stored string. */ 00049 NMDErrorCode NMDStringDestroy(NMD_string str) 00050 { 00051 CHECKHASNMDCOOKIE(str); 00052 NMD_FREE(str->t); 00053 NMD_FREE(str); 00054 return 0; 00055 } 00056 00057 #undef __FUNCT__ 00058 #define __FUNCT__ "NMDStringGetString" 00059 /*! Return a pointer to the string in a string object */ 00060 NMDErrorCode NMDStringGetString(NMD_string str,const char **t) 00061 { 00062 CHECKHASNMDCOOKIE(str); 00063 *t = str->t; 00064 return 0; 00065 } 00066 00067 #undef __FUNCT__ 00068 #define __FUNCT__ "NMDStringConcat" 00069 /*! Concatenate string objects, with delimiter characters 00070 before, after, in between. All delimiters, and the second string, 00071 can be null. 00072 */ 00073 NMDErrorCode NMDStringConcat 00074 (char s1,NMD_string str1,char s2,NMD_string str2,char s3,NMD_string *r_str) 00075 { 00076 NMD_string str; NMDErrorCode ierr; int l; 00077 CHECKHASNMDCOOKIE(str1); 00078 00079 l = str1->n + ( str2 ? str2->n : 0 ) + (s1!=0) + (s2!=0) + (s3!=0); 00080 ierr = NMDStringCreateOfSize(l,&str); NMD_ERR_RETURN(ierr); 00081 00082 l = 0; 00083 if (s1) { 00084 if (l+1>str->n) NMD_ERR_REPORT("string overflow"); 00085 memcpy(str->t+l,&s1,1); 00086 } 00087 00088 l = strlen(str->t); 00089 if (l+str1->n>str->n) NMD_ERR_REPORT("string overflow"); 00090 memcpy(str->t+l,str1->t,str1->n); 00091 00092 if (s2) { 00093 CHECKHASNMDCOOKIE(str2); 00094 l = strlen(str->t); 00095 if (l+1>str->n) NMD_ERR_REPORT("string overflow"); 00096 memcpy(str->t+l,&s2,1); 00097 } 00098 00099 if (str2) { 00100 l = strlen(str->t); 00101 if (l+str2->n>str->n) NMD_ERR_REPORT("string overflow"); 00102 memcpy(str->t+l,str2->t,str2->n); 00103 } 00104 00105 if (s3) { 00106 l = strlen(str->t); 00107 if (l+1>str->n) NMD_ERR_REPORT("string overflow"); 00108 memcpy(str->t+l,&s3,1); 00109 } 00110 00111 *r_str = str; 00112 return 0; 00113 } 00114 00115 #undef __FUNCT__ 00116 #define __FUNCT__ "NMDStringAppend" 00117 /*! A version of NMDStringConcat() that appends to string 1, 00118 rather than creating a new string. 00119 */ 00120 NMDErrorCode NMDStringAppend 00121 (char s1,NMD_string *str1,char s2,NMD_string str2,char s3) 00122 { 00123 NMD_string nnew; NMDErrorCode ierr; 00124 CHECKHASNMDCOOKIE(*str1); 00125 CHECKHASNMDCOOKIE(str2); 00126 ierr = NMDStringConcat(s1,*str1,s2,str2,s3,&nnew); NMD_ERR_RETURN(ierr); 00127 ierr = NMDStringDestroy(*str1); NMD_ERR_RETURN(ierr); 00128 *str1 = nnew; 00129 return 0; 00130 }