NMD
nmdutil.c
Go to the documentation of this file.
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 }