Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

ffstring.c

Go to the documentation of this file.
00001 /*
00002  * finflect - Algorithms and tools for inflecting Finnish nouns
00003  * Copyright (C) 2004, 2005  The FinFlect Team
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  *
00019  *
00020  * For the complete legal text of the GNU Lesser General Public License,
00021  * see the file LICENSE. For a complete list of authors and copyright
00022  * holders, see the file AUTHORS.
00023  */
00024 
00025 /**
00026  * @file ffstring.c Implements the operations (declared in ffstring.h) related to the
00027  * ffstring string data type.
00028  */
00029 
00030 #include <sys/types.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <strings.h>
00035 #include <ctype.h>
00036 
00037 
00038 #include "ffstring.h"
00039 
00040 static ffint32 _ffstring_instance_counter = 0;
00041 
00042 ffint32 ffstring_create(const ffchar* source, ffstring* target)
00043 {
00044   ffint32 sourcelen = strlen(source);
00045   target->str = (char*) malloc(sourcelen+1);
00046   if(!target->str)
00047   {
00048     perror("malloc");
00049     return -1;
00050   }
00051 
00052   /* Add default values */
00053   strcpy(target->str, source);
00054   target->len = sourcelen;
00055 
00056   _ffstring_instance_counter++;
00057 
00058   return 0;
00059 }
00060 
00061 ffint32 ffstring_delete(ffstring* target)
00062 {
00063 
00064   free(target->str);
00065 
00066   _ffstring_instance_counter--;
00067 
00068   return 0;
00069 }
00070 
00071 ffint32 ffstring_copy(const ffstring* source, ffstring* target)
00072 {
00073   return ffstring_create(source->str,target);
00074 }
00075 
00076 ffint32 ffstring_move_and_delete(ffstring* source, ffstring* target)
00077 {
00078   ffstring_delete(target);
00079   ffstring_copy(source, target);
00080   ffstring_delete(source);
00081   return 0;
00082 }
00083 
00084 
00085 
00086 /* Other functions */
00087 
00088 ffint32 ffstring_dfe(ffstring* target, ffuint32 count)
00089 {
00090 
00091   ffuint32 nlen;
00092   char* n;
00093 
00094   /* Check the lengt */
00095   nlen = target->len-count+1;
00096   if (nlen < 1)
00097   {
00098     printf("ffstring_dfe: New length smaller than 1\n");
00099     return -2;
00100   }
00101 
00102   /* Allocate memory */
00103   n = (char*) realloc(target->str, nlen);
00104   if (!n)
00105   {
00106     perror("realloc");
00107     return -1;
00108   }
00109 
00110   /* Apply changes */
00111   target->str = n;
00112   target->str[target->len-count] = '\0';
00113   target->len -= count;
00114 
00115   return 0;
00116 }
00117 
00118 ffint32 ffstring_rfe(ffstring* target, ffuint32 count, char* append)
00119 {
00120 
00121   char* n;
00122   ffuint32 nlen;
00123   ffuint32 alen;
00124 
00125 
00126   alen = strlen(append);
00127   nlen = target->len-count+alen+1;
00128 
00129   if ( nlen < 1 )
00130   {
00131     printf("ffstring_rfe: New length smaller than 1");
00132     return -2;
00133   }
00134 
00135 
00136   /* Allocate new space */
00137   n = (char*) realloc(target->str, nlen);
00138   if (!n)
00139   {
00140     perror("realloc");
00141     return -1;
00142   }
00143 
00144   /* Apply changes
00145      - Break the old string where deleted part starts
00146        and overwrite it with new
00147   */
00148   target->str = n;
00149   target->str[target->len-count] = '\0';
00150   strcat(target->str,append);
00151   target->len += alen-count;
00152   return 0;
00153 }
00154 
00155 ffint32 ffstring_rfe_ff(ffstring* target, ffuint32 count, const ffstring* append)
00156 {
00157   return ffstring_rfe(target, count, append->str);
00158 }
00159 
00160 ffint32 ffstring_append(ffstring* target, char* append)
00161 {
00162   char* n;
00163   ffuint32 alen = strlen(append);
00164 
00165   /* Allocate new space */
00166   n = (char*) realloc(target->str, target->len+alen+1);
00167   if (!n)
00168   {
00169     perror("realloc");
00170     return -1;
00171   }
00172 
00173   /* Apply changes */
00174   target->str = n;
00175   strcat(target->str,append);
00176   target->len += alen;
00177 
00178   return 0;
00179 }
00180 
00181 ffint32 ffstring_append_ff(ffstring* target, const ffstring* source)
00182 {
00183   /**
00184    * @todo 
00185    * We already know the length of the source ffstring, so why not create an
00186    * optimized version?
00187    */
00188   return ffstring_append(target, source->str);
00189 }
00190 
00191 ffint32 ffstring_instcount()
00192 {
00193   return _ffstring_instance_counter;
00194 }
00195 
00196 ffint32 ffstring_tail(const ffstring* source, ffint32 count, ffstring* target)
00197 {
00198   ffint32 offset = source->len - count;
00199   if (offset < 0)
00200     return -2;
00201 
00202   return ffstring_create(source->str + offset, target);
00203 }
00204 
00205 ffint32 ffstring_tolower(ffstring* target)
00206 {
00207   ffchar* i;
00208   for (i = target->str; i < target->str + target->len; ++i)
00209     *i = tolower(*i);
00210   return 0;
00211 }
00212 
00213 ffint32 ffstring_lower(const ffstring* source, ffstring* target)
00214 {
00215   ffint32 error = 0;
00216   if ((error = ffstring_create(source->str, target)))
00217     return error;
00218   return ffstring_tolower(target);   
00219 }
00220 
00221 ffint32 ffstring_compare(const ffstring* left, const ffchar* right)
00222 {
00223   return strcmp(left->str, right);
00224 }
00225 
00226 ffint32 ffstring_compare_ci(const ffstring* left, const ffchar* right)
00227 {
00228   return strcasecmp(left->str, right);
00229 }
00230 
00231 ffint32 ffstring_compare_ff(const ffstring* left, const ffstring* right)
00232 {
00233   return strcmp(left->str, right->str);
00234 }
00235 
00236 ffint32 ffstring_compare_ff_ci(const ffstring* left, const ffstring* right)
00237 {
00238   return strcasecmp(left->str, right->str);
00239 }
00240 
00241 ffint32 ffstring_decinst()
00242 {
00243   if (_ffstring_instance_counter <= 0)
00244     return -1;
00245   else {
00246     --_ffstring_instance_counter;
00247     return 0;
00248   }
00249 }
00250 
00251 ffint32 ffstring_compare_tail(const ffstring* left, ffuint32 count, const ffchar* right)
00252 {
00253   ffstring tail;
00254   ffint32 result;
00255   if ( left->len < count )
00256     return -1;
00257   ffstring_tail(left, count, &tail);
00258   result = ffstring_compare(&tail, right);
00259   ffstring_delete(&tail);
00260   return result;
00261 }
00262 
00263 ffint32 ffstring_compare_tail_ci(const ffstring* left, ffuint32 count, const ffchar* right)
00264 {
00265   ffstring tail;
00266   ffint32 result;
00267   if ( left->len < count )
00268     return -1;
00269   ffstring_tail(left, count, &tail);
00270   result = ffstring_compare_ci(&tail, right);
00271   ffstring_delete(&tail);
00272   return result;
00273 }
00274 
00275 ffint32 ffstring_compare_tail_ff(const ffstring* left, ffuint32 count, const ffstring* right)
00276 {
00277   ffstring tail;
00278   ffint32 result;
00279   if ( left->len < count )
00280     return -1;
00281   ffstring_tail(left, count, &tail);
00282   result = ffstring_compare_ff(&tail, right);
00283   ffstring_delete(&tail);
00284   return result;
00285 }
00286 
00287 ffint32 ffstring_compare_tail_ff_ci(const ffstring* left, ffuint32 count, const ffstring* right)
00288 {
00289   ffstring tail;
00290   ffint32 result;
00291   if ( left->len < count )
00292     return -1;
00293   ffstring_tail(left, count, &tail);
00294   result = ffstring_compare_ff_ci(&tail, right);
00295   ffstring_delete(&tail);
00296   return result;
00297 }
00298 
00299 ffchar ffstring_last(const ffstring* source)
00300 {
00301   if(source->len < 1)
00302     return 0;
00303   else
00304     return *(source->str + source->len - 1);
00305 }
00306 
00307 ffint32 ffstring_compare_last(const ffstring* left, const ffchar right)
00308 {
00309   /**
00310    * @todo Umlauts
00311    */
00312   ffchar left_last;
00313   left_last = ffstring_last(left);
00314   if(left_last < right)
00315     return -1;
00316   else if(left_last == right)
00317     return 0;
00318   else
00319     return 1;
00320 }
00321 
00322 ffint32 ffstring_compare_last_ci(const ffstring* left, const ffchar right)
00323 {
00324   /**
00325    * @todo Umlauts
00326    */
00327   ffchar left_lower, right_lower;
00328   left_lower = tolower(ffstring_last(left));
00329   right_lower = tolower(right);
00330     if(left_lower < right_lower)
00331     return -1;
00332   else if(left_lower == right_lower)
00333     return 0;
00334   else
00335     return 1;
00336 }
00337 
00338 ffbool ffstring_equals(const ffstring* left, const ffchar* right)
00339 {
00340   return !ffstring_compare(left, right);
00341 }
00342 
00343 ffbool ffstring_equals_ci(const ffstring* left, const ffchar* right)
00344 {
00345   return !ffstring_compare_ci(left, right);
00346 }
00347 
00348 ffbool ffstring_equals_ff(const ffstring* left, const ffstring* right)
00349 {
00350   return !ffstring_compare_ff(left, right);
00351 }
00352 
00353 ffbool ffstring_equals_ff_ci(const ffstring* left, const ffstring* right)
00354 {
00355   return !ffstring_compare_ff_ci(left, right);
00356 }
00357 
00358 ffbool ffstring_tail_equals(const ffstring* left, const ffint32 count, const ffchar* right)
00359 {
00360   return !ffstring_compare_tail(left, count, right);
00361 }
00362 
00363 ffbool ffstring_tail_equals_ci(const ffstring* left, const ffint32 count, const ffchar* right)
00364 {
00365   return !ffstring_compare_tail_ci(left, count, right);
00366 }
00367 
00368 ffbool ffstring_tail_equals_ff(const ffstring* left, const ffint32 count, const ffstring* right)
00369 {
00370   return !ffstring_compare_tail_ff(left, count, right);
00371 }
00372 
00373 ffbool ffstring_tail_equals_ff_ci(const ffstring* left, const ffint32 count, const ffstring* right)
00374 {
00375   return !ffstring_compare_tail_ff_ci(left, count, right);
00376 }
00377 
00378 ffbool ffstring_last_equals(const ffstring* left, ffchar right)
00379 {
00380   return !ffstring_compare_last(left, right);
00381 }
00382 
00383 ffbool ffstring_last_equals_ci(const ffstring* left, ffchar right)
00384 {
00385   return !ffstring_compare_last_ci(left, right);
00386 }

Generated on Sun May 15 21:50:47 2005 for FinFlect by  doxygen 1.4.1