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 #include "ffstring.h"
00038 #include "ffutil.h"
00039 #include "ffconfig.h"
00040 #include "fferror.h"
00041 
00042 static ffint32 _ffstring_instance_counter = 0;
00043 
00044 ffint32 ffstring_create(const ffchar* source, ffstring* target) {
00045   ffint32 sourcelen = strlen(source);
00046   target->str = (char*) malloc(sourcelen+1);
00047   if (!target->str) {
00048     FF_PRINTERROR("Holy Shit! Malloc failed! omglol...");
00049     return FFERR_MEM;
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   free(target->str);
00063   target->str = NULL;
00064 
00065   _ffstring_instance_counter--;
00066 
00067   return 0;
00068 }
00069 
00070 ffint32 ffstring_copy(const ffstring* source, ffstring* target) {
00071   return ffstring_create(source->str,target);
00072 }
00073 
00074 /* Other functions */
00075 
00076 ffint32 ffstring_dfe(ffstring* target, ffuint32 count) {
00077   ffuint32 nlen;
00078   char* n;
00079 
00080   /* Check the lenght */
00081   nlen = target->len-count+1;
00082   if (nlen < 1) {
00083     FF_PRINTERROR("in function 'ffstring_dfe': New length smaller than 1");
00084     return FFERR_ARGUMENT;
00085   }
00086 
00087   /* Allocate memory */
00088   n = (char*) realloc(target->str, nlen);
00089   if (!n) {
00090     FF_PRINTERROR("in function 'ffstring_dfe': realloc failed! buy more memory X(");
00091     return FFERR_MEM;
00092   }
00093 
00094   /* Apply changes */
00095   target->str = n;
00096   target->str[target->len-count] = '\0';
00097   target->len -= count;
00098 
00099   return 0;
00100 }
00101 
00102 ffint32 ffstring_rfe(ffstring* target, ffuint32 count, char* append) {
00103   char* n;
00104   ffuint32 nlen;
00105   ffuint32 alen;
00106 
00107 
00108   alen = strlen(append);
00109   nlen = target->len-count+alen+1;
00110 
00111   if (nlen < 1) {
00112     FF_PRINTERROR("in function 'ffstring_rfe': New length smaller than 1");
00113     return FFERR_ARGUMENT;
00114   }
00115 
00116 
00117   /* Allocate new space */
00118   n = (char*) realloc(target->str, nlen);
00119   if (!n) {
00120     FF_PRINTERROR("in function 'ffstring_rfe': realloc failed!");
00121     return FFERR_MEM;
00122   }
00123 
00124   /* Apply changes
00125      - Break the old string where deleted part starts
00126        and overwrite it with new
00127   */
00128   target->str = n;
00129   target->str[target->len-count] = '\0';
00130   strcat(target->str,append);
00131   target->len += alen-count;
00132   return 0;
00133 }
00134 
00135 ffint32 ffstring_rfe_ff(ffstring* target, ffuint32 count, const ffstring* append) {
00136   return ffstring_rfe(target, count, append->str);
00137 }
00138 
00139 ffint32 ffstring_append(ffstring* target, char* append) {
00140   char* n;
00141   ffuint32 alen = strlen(append);
00142 
00143   /* Allocate new space */
00144   n = (char*) realloc(target->str, target->len+alen+1);
00145   if (!n) {
00146     FF_PRINTERROR("in function 'ffstring_append': realloc failed!");
00147     return FFERR_MEM;
00148   }
00149 
00150   /* Apply changes */
00151   target->str = n;
00152   strcat(target->str,append);
00153   target->len += alen;
00154 
00155   return 0;
00156 }
00157 
00158 ffint32 ffstring_append_ff(ffstring* target, const ffstring* source) {
00159   /**
00160    * @todo 
00161    * We already know the length of the source ffstring, so why not create an
00162    * optimized version?
00163    */
00164   return ffstring_append(target, source->str);
00165 }
00166 
00167 ffint32 ffstring_instcount(void) {
00168   return _ffstring_instance_counter;
00169 }
00170 
00171 ffint32 ffstring_tail(const ffstring* source, ffint32 count, ffstring* target) {
00172   ffint32 offset = source->len - count;
00173   if (offset < 0) {
00174     FF_PRINTERROR("in function 'ffstring_tail': offset is smaller than 0 and obviously someone has fucked up!");
00175     return FFERR_ARGUMENT;
00176   }
00177   return ffstring_create(source->str + offset, target);
00178 }
00179 
00180 ffint32 ffstring_tolower(ffstring* target) {
00181   ffchar* i;
00182   for (i = target->str; i < target->str + target->len; ++i) {
00183     *i = tolower(*i);
00184   }
00185   return 0;
00186 }
00187 
00188 ffint32 ffstring_lower(const ffstring* source, ffstring* target) {
00189   ffint32 error = 0;
00190   if ((error = ffstring_create(source->str, target))) {
00191     return error;
00192   }
00193   return ffstring_tolower(target);
00194 }
00195 
00196 ffint32 ffstring_compare(const ffstring* left, const ffchar* right) {
00197   return strcmp(left->str, right);
00198 }
00199 
00200 ffint32 ffstring_compare_ci(const ffstring* left, const ffchar* right) {
00201   ffint32 result;
00202   ffstring rightff;
00203   ffstring leftlower;
00204   ffstring rightlower;
00205 
00206   ffstring_create(right, &rightff);
00207   ffutil_tolower(left,&leftlower);
00208   ffutil_tolower(&rightff,&rightlower);
00209 
00210   result = strcmp(leftlower.str, rightlower.str);
00211 
00212   ffstring_delete(&rightff);
00213   ffstring_delete(&leftlower);
00214   ffstring_delete(&rightlower);
00215 
00216   return result;
00217 }
00218 
00219 ffint32 ffstring_compare_ff(const ffstring* left, const ffstring* right) {
00220   return strcmp(left->str, right->str);
00221 }
00222 
00223 ffint32 ffstring_compare_ff_ci(const ffstring* left, const ffstring* right) {
00224   ffint32 result;
00225   ffstring leftlower;
00226   ffstring rightlower;
00227 
00228   ffutil_tolower(left,&leftlower);
00229   ffutil_tolower(right,&rightlower);
00230 
00231   result = strcmp(leftlower.str, rightlower.str);
00232 
00233   ffstring_delete(&leftlower);
00234   ffstring_delete(&rightlower);
00235 
00236   return result;
00237 }
00238 
00239 ffint32 ffstring_decinst(void) {
00240   if (_ffstring_instance_counter <= 0) {
00241     FF_PRINTERROR("in function 'ffstring_decinst': memory management is b0rked!");
00242     return FFERR_MEM;
00243   } else {
00244     --_ffstring_instance_counter;
00245     return 0;
00246   }
00247 }
00248 
00249 ffint32 ffstring_compare_tail(const ffstring* left, ffuint32 count, const ffchar* right) {
00250   ffstring tail;
00251   ffint32 result;
00252 
00253   if (left->len < count) {
00254     return -1;
00255   }
00256 
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   ffstring tail;
00265   ffint32 result;
00266 
00267   if (left->len < count) {
00268     return -1;
00269   }
00270 
00271   ffstring_tail(left, count, &tail);
00272   result = ffstring_compare_ci(&tail, right);
00273   ffstring_delete(&tail);
00274   return result;
00275 }
00276 
00277 ffint32 ffstring_compare_tail_ff(const ffstring* left, ffuint32 count, const ffstring* right) {
00278   ffstring tail;
00279   ffint32 result;
00280 
00281   if (left->len < count) {
00282     return -1;
00283   }
00284 
00285   ffstring_tail(left, count, &tail);
00286   result = ffstring_compare_ff(&tail, right);
00287   ffstring_delete(&tail);
00288   return result;
00289 }
00290 
00291 ffint32 ffstring_compare_tail_ff_ci(const ffstring* left, ffuint32 count, const ffstring* right) {
00292   ffstring tail;
00293   ffint32 result;
00294 
00295   if (left->len < count) {
00296     return -1;
00297   }
00298 
00299   ffstring_tail(left, count, &tail);
00300   result = ffstring_compare_ff_ci(&tail, right);
00301   ffstring_delete(&tail);
00302   return result;
00303 }
00304 
00305 ffchar ffstring_last(const ffstring* source) {
00306   if (source->len < 1) {
00307     return 0;
00308   } else {
00309     return *(source->str + source->len - 1);
00310   }
00311 }
00312 
00313 ffint32 ffstring_compare_last(const ffstring* left, const ffchar right) {
00314   /**
00315    * @todo Umlauts
00316    */
00317   ffchar left_last = ffstring_last(left);
00318 
00319   if (left_last < right) {
00320     return -1;
00321   } else if (left_last == right) {
00322     return 0;
00323   } else {
00324     return 1;
00325   }
00326 }
00327 
00328 ffint32 ffstring_compare_last_ci(const ffstring* left, const ffchar right) {
00329   /**
00330    * @todo Umlauts
00331    */
00332   ffchar left_lower, right_lower;
00333 
00334   left_lower = tolower(ffstring_last(left));
00335   right_lower = tolower(right);
00336 
00337   if (left_lower < right_lower) {
00338     return -1;
00339   } else if (left_lower == right_lower) {
00340     return 0;
00341   } else {
00342     return 1;
00343   }
00344 }
00345 
00346 ffbool ffstring_equals(const ffstring* left, const ffchar* right) {
00347   return !ffstring_compare(left, right);
00348 }
00349 
00350 ffbool ffstring_equals_ci(const ffstring* left, const ffchar* right) {
00351   ffuint32 i;
00352 
00353   if (left->len != strlen(right)) {
00354     return 0;
00355   }
00356 
00357   for (i = 0;i < left->len; i++) {
00358     if (ffutil_ffchar_tolower(left->str[i]) != ffutil_ffchar_tolower(right[i])) {
00359       return 0;
00360     }
00361   }
00362   return 1;
00363 }
00364 
00365 ffbool ffstring_equals_ff(const ffstring* left, const ffstring* right) {
00366   return !ffstring_compare_ff(left, right);
00367 }
00368 
00369 ffbool ffstring_equals_ff_ci(const ffstring* left, const ffstring* right) {
00370   ffuint32 i;
00371 
00372   if (left->len != right->len) {
00373     return 0;
00374   }
00375 
00376   for (i = 0;i < left->len; i++) {
00377     if (ffutil_ffchar_tolower(left->str[i]) != ffutil_ffchar_tolower(right->str[i])) {
00378       return 0;
00379     }
00380   }
00381   return 1;
00382 }
00383 
00384 ffbool ffstring_tail_equals(const ffstring* left, const ffint32 count, const ffchar* right) {
00385   return !ffstring_compare_tail(left, count, right);
00386 }
00387 
00388 ffbool ffstring_tail_equals_ci(const ffstring* left, const ffint32 count, const ffchar* right) {
00389   return !ffstring_compare_tail_ci(left, count, right);
00390 }
00391 
00392 ffbool ffstring_tail_equals_ff(const ffstring* left, const ffint32 count, const ffstring* right) {
00393   return !ffstring_compare_tail_ff(left, count, right);
00394 }
00395 
00396 ffbool ffstring_tail_equals_ff_ci(const ffstring* left, const ffint32 count, const ffstring* right) {
00397   return !ffstring_compare_tail_ff_ci(left, count, right);
00398 }
00399 
00400 ffbool ffstring_last_equals(const ffstring* left, ffchar right) {
00401   return !ffstring_compare_last(left, right);
00402 }
00403 
00404 ffbool ffstring_last_equals_ci(const ffstring* left, ffchar right) {
00405   return !ffstring_compare_last_ci(left, right);
00406 }

Generated on Thu Jun 2 23:16:59 2005 for FinFlect by  doxygen 1.4.2