00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 #define KATE_INTERNAL
00011 #include "kate_internal.h"
00012 
00013 #include <stdio.h>
00014 #ifdef HAVE_STDLIB_H
00015 #include <stdlib.h>
00016 #endif
00017 #ifdef HAVE_STRING_H
00018 #include <string.h>
00019 #endif
00020 #include "kate/kate.h"
00021 
00029 int kate_comment_init(kate_comment *kc)
00030 {
00031   if (!kc) return KATE_E_INVALID_PARAMETER;
00032 
00033   kc->user_comments=NULL;
00034   kc->comment_lengths=NULL;
00035   kc->comments=0;
00036   kc->vendor=NULL;
00037 
00038   return 0;
00039 }
00040 
00048 int kate_comment_clear(kate_comment *kc)
00049 {
00050   int n;
00051 
00052   if (!kc) return KATE_E_INVALID_PARAMETER;
00053 
00054   for (n=0;n<kc->comments;++n) kate_free(kc->user_comments[n]);
00055   if (kc->user_comments) kate_free(kc->user_comments);
00056   if (kc->comment_lengths) kate_free(kc->comment_lengths);
00057   if (kc->vendor) kate_free(kc->vendor);
00058 
00059   return 0;
00060 }
00061 
00062 static int kate_comment_check_tag(const char *tag,size_t len)
00063 {
00064   if (!tag) return KATE_E_INVALID_PARAMETER;
00065 
00066   if (len==0) return KATE_E_BAD_TAG;
00067   while (len--) {
00068     int c=*tag++;
00069     if (c<0x20 || c>0x7d || c=='=') return KATE_E_BAD_TAG;
00070   }
00071   return 0;
00072 }
00073 
00086 int kate_comment_add_length(kate_comment *kc,const char *comment,size_t len)
00087 {
00088   int *cl;
00089   char **uc;
00090   const char *equals;
00091   int ret;
00092 
00093   if (!kc || !comment) return KATE_E_INVALID_PARAMETER;
00094 
00095   ret=kate_check_add_overflow(kc->comments,1,NULL);
00096   if (ret<0) return ret;
00097   ret=kate_check_add_overflow(len,1,NULL);
00098   if (ret<0) return ret;
00099 
00100   equals=memchr(comment,'=',len);
00101   if (!equals) return KATE_E_BAD_TAG;
00102   ret=kate_comment_check_tag(comment,equals-comment);
00103   if (ret<0) return ret;
00104   ret=kate_text_validate(kate_utf8,equals,len-(equals-comment));
00105   if (ret<0) return ret;
00106 
00107   uc=kate_checked_realloc(kc->user_comments,(kc->comments+1),sizeof(char*));
00108   if (!uc) return KATE_E_OUT_OF_MEMORY;
00109   kc->user_comments=uc;
00110   cl=kate_checked_realloc(kc->comment_lengths,(kc->comments+1),sizeof(int));
00111   if (!cl) return KATE_E_OUT_OF_MEMORY;
00112   kc->comment_lengths=cl;
00113 
00114   kc->user_comments[kc->comments]=(char*)kate_malloc(len+1);
00115   if (!kc->user_comments[kc->comments]) return KATE_E_OUT_OF_MEMORY;
00116   memcpy(kc->user_comments[kc->comments],comment,len);
00117   kc->user_comments[kc->comments][len]=0;
00118   kc->comment_lengths[kc->comments]=len;
00119 
00120   ++kc->comments;
00121 
00122   return 0;
00123 }
00124 
00136 int kate_comment_add(kate_comment *kc,const char *comment)
00137 {
00138   if (!kc || !comment) return KATE_E_INVALID_PARAMETER;
00139 
00140   return kate_comment_add_length(kc,comment,strlen(comment));
00141 }
00142 
00156 int kate_comment_add_tag(kate_comment *kc,const char *tag,const char *value)
00157 {
00158   char *comment;
00159 
00160   if (!kc || !tag || !value) return KATE_E_INVALID_PARAMETER;
00161 
00162   comment=(char*)kate_malloc(strlen(tag)+1+strlen(value)+1);
00163   if (!comment) return KATE_E_OUT_OF_MEMORY;
00164   sprintf(comment,"%s=%s",tag,value);
00165   kate_comment_add(kc,comment);
00166   kate_free(comment);
00167 
00168   return 0;
00169 }
00170 
00184 const char *kate_comment_query(const kate_comment *kc,const char *tag,int count)
00185 {
00186   int n;
00187   size_t bytes;
00188 
00189   if (!kc) return NULL;
00190 
00191   for (n=0;n<kc->comments;++n) {
00192     const char *eq=strchr(kc->user_comments[n],'=');
00193     if (!eq) continue; 
00194     bytes=eq-kc->user_comments[n];
00195     if (!kate_ascii_strncasecmp(tag,kc->user_comments[n],bytes)) {
00196       if (count==0) return eq+1;
00197       --count;
00198     }
00199   }
00200   
00201   return NULL;
00202 }
00203 
00213 int kate_comment_query_count(const kate_comment *kc,const char *tag)
00214 {
00215   int n,count;
00216   size_t bytes;
00217 
00218   if (!kc) return KATE_E_INVALID_PARAMETER;
00219 
00220   count=0;
00221   for (n=0;n<kc->comments;++n) {
00222     const char *eq=strchr(kc->user_comments[n],'=');
00223     if (!eq) continue; 
00224     bytes=eq-kc->user_comments[n];
00225     if (!kate_ascii_strncasecmp(tag,kc->user_comments[n],bytes)) {
00226       ++count;
00227     }
00228   }
00229 
00230   return count;
00231 }
00232