LCOV - code coverage report
Current view: top level - Unicode - ustring.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 129 648 19.9 %
Date: 2017-08-04 Functions: 14 80 17.5 %

          Line data    Source code
       1             : /* Copyright (C) 2000-2012 by George Williams */
       2             : /*
       3             :  * Redistribution and use in source and binary forms, with or without
       4             :  * modification, are permitted provided that the following conditions are met:
       5             : 
       6             :  * Redistributions of source code must retain the above copyright notice, this
       7             :  * list of conditions and the following disclaimer.
       8             : 
       9             :  * Redistributions in binary form must reproduce the above copyright notice,
      10             :  * this list of conditions and the following disclaimer in the documentation
      11             :  * and/or other materials provided with the distribution.
      12             : 
      13             :  * The name of the author may not be used to endorse or promote products
      14             :  * derived from this software without specific prior written permission.
      15             : 
      16             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
      17             :  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
      18             :  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
      19             :  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      20             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      21             :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
      22             :  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      23             :  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      24             :  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
      25             :  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             :  */
      27             : #include <fontforge-config.h>
      28             : 
      29             : #include <stddef.h>
      30             : #include "ustring.h"
      31             : #include "utype.h"
      32             : 
      33           0 : long uc_strcmp(const unichar_t *str1,const char *str2) {
      34             :     long ch1, ch2;
      35             :     for (;;) {
      36           0 :         ch1 = *str1++; ch2 = *(unsigned char *) str2++ ;
      37           0 :         if ( ch1!=ch2 || ch1=='\0' )
      38           0 : return(ch1-ch2);
      39           0 :     }
      40             : }
      41             : 
      42           0 : long uc_strncmp(const unichar_t *str1,const char *str2,int n) {
      43             :     long ch1, ch2;
      44           0 :     while ( --n>=0 ) {
      45           0 :         ch1 = *str1++; ch2 = *(unsigned char *) str2++ ;
      46           0 :         if ( ch1!=ch2 || ch1=='\0' )
      47           0 : return(ch1-ch2);
      48             :     }
      49           0 : return( 0 );
      50             : }
      51             : 
      52           0 : long uc_strmatch(const unichar_t *str1, const char *str2) {
      53             :     long ch1, ch2;
      54             :     for (;;) {
      55           0 :         ch1 = *str1++; ch2 = *(unsigned char *) str2++ ;
      56           0 :         ch1 = tolower(ch1);
      57           0 :         ch2 = tolower(ch2);
      58           0 :         if ( ch1!=ch2 || ch1=='\0' )
      59           0 : return(ch1-ch2);
      60           0 :     }
      61             : }
      62             : 
      63           0 : long uc_strnmatch(const unichar_t *str1, const char *str2, int len) {
      64             :     long ch1, ch2;
      65           0 :     for (;--len>=0;) {
      66           0 :         ch1 = *str1++; ch2 = *(unsigned char *) str2++ ;
      67           0 :         ch1 = tolower(ch1);
      68           0 :         ch2 = tolower(ch2);
      69           0 :         if ( ch1!=ch2 || ch1=='\0' || len<=0 )
      70           0 : return(ch1-ch2);
      71             :     }
      72           0 : return( 0 );
      73             : }
      74             : 
      75           0 : long u_strnmatch(const unichar_t *str1, const unichar_t *str2, int len) {
      76             :     long ch1, ch2;
      77           0 :     for (;--len>=0;) {
      78           0 :         ch1 = *str1++; ch2 = *str2++ ;
      79           0 :         ch1 = tolower(ch1);
      80           0 :         ch2 = tolower(ch2);
      81           0 :         if ( ch1!=ch2 || ch1=='\0' || len<=0 )
      82           0 : return(ch1-ch2);
      83             :     }
      84           0 : return( 0 );
      85             : }
      86             : 
      87           0 : long u_strcmp(const unichar_t *str1,const unichar_t *str2) {
      88             :     long ch1, ch2;
      89             :     for (;;) {
      90           0 :         ch1 = *str1++; ch2 = *str2++ ;
      91           0 :         if ( ch1!=ch2 || ch1=='\0' )
      92           0 : return(ch1-ch2);
      93           0 :     }
      94             : }
      95             : 
      96           0 : long u_strncmp(const unichar_t *str1,const unichar_t *str2,int n) {
      97             :     long ch1, ch2;
      98           0 :     while ( --n>=0 ) {
      99           0 :         ch1 = *str1++; ch2 = *str2++ ;
     100           0 :         if ( ch1!=ch2 || ch1=='\0' )
     101           0 : return(ch1-ch2);
     102             :     }
     103           0 : return( 0 );
     104             : }
     105             : 
     106           0 : long u_strmatch(const unichar_t *str1, const unichar_t *str2) {
     107             :     long ch1, ch2;
     108             :     for (;;) {
     109           0 :         ch1 = *str1++; ch2 = *str2++ ;
     110           0 :         ch1 = tolower(ch1);
     111           0 :         ch2 = tolower(ch2);
     112           0 :         if ( ch1!=ch2 || ch1=='\0' )
     113           0 : return(ch1-ch2);
     114           0 :     }
     115             : }
     116             : 
     117           0 : void cu_strcpy(char *to, const unichar_t *from) {
     118             :     register unichar_t ch;
     119           0 :     while ( (ch = *from++) != '\0' )
     120           0 :         *(to++) = ch;
     121           0 :     *to = 0;
     122           0 : }
     123             : 
     124           0 : void uc_strcpy(unichar_t *to, const char *from) {
     125             :     register unichar_t ch;
     126           0 :     while ( (ch = *(unsigned char *) from++) != '\0' )
     127           0 :         *(to++) = ch;
     128           0 :     *to = 0;
     129           0 : }
     130             : 
     131           0 : void u_strcpy(unichar_t *to, const unichar_t *from) {
     132             :     register unichar_t ch;
     133           0 :     while ( (ch = *from++) != '\0' )
     134           0 :         *(to++) = ch;
     135           0 :     *to = 0;
     136           0 : }
     137             : 
     138           0 : char *cc_strncpy(char *to, const char *from, int len) {
     139           0 :     if( !from ) {
     140           0 :         to[0] = '\0';
     141           0 :         return to;
     142             :     }
     143           0 :     strncpy( to, from, len );
     144           0 :     return to;
     145             : }
     146             : 
     147             : 
     148           0 : void u_strncpy(register unichar_t *to, const unichar_t *from, int len) {
     149             :     register unichar_t ch;
     150           0 :     while ( (ch = *from++) != '\0' && --len>=0 )
     151           0 :         *(to++) = ch;
     152           0 :     *to = 0;
     153           0 : }
     154             : 
     155           0 : void cu_strncpy(register char *to, const unichar_t *from, int len) {
     156             :     register unichar_t ch;
     157           0 :     while ( (ch = *from++) != '\0' && --len>=0 )
     158           0 :         *(to++) = ch;
     159           0 :     *to = 0;
     160           0 : }
     161             : 
     162           0 : void uc_strncpy(register unichar_t *to, const char *from, int len) {
     163             :     register unichar_t ch;
     164           0 :     while ( (ch = *(unsigned char *) from++) != '\0' && --len>=0 )
     165           0 :         *(to++) = ch;
     166           0 :     *to = 0;
     167           0 : }
     168             : 
     169           0 : void uc_strcat(unichar_t *to, const char *from) {
     170           0 :     uc_strcpy(to+u_strlen(to),from);
     171           0 : }
     172             : 
     173           0 : void uc_strncat(unichar_t *to, const char *from,int len) {
     174           0 :     uc_strncpy(to+u_strlen(to),from,len);
     175           0 : }
     176             : 
     177           0 : void cu_strcat(char *to, const unichar_t *from) {
     178           0 :     cu_strcpy(to+strlen(to),from);
     179           0 : }
     180             : 
     181           0 : void cu_strncat(char *to, const unichar_t *from, int len) {
     182           0 :     cu_strncpy(to+strlen(to),from,len);
     183           0 : }
     184             : 
     185           0 : void u_strcat(unichar_t *to, const unichar_t *from) {
     186           0 :     u_strcpy(to+u_strlen(to),from);
     187           0 : }
     188             : 
     189           0 : void u_strncat(unichar_t *to, const unichar_t *from, int len) {
     190           0 :     u_strncpy(to+u_strlen(to),from,len);
     191           0 : }
     192             : 
     193             : 
     194      203033 : int u_strlen(register const unichar_t *str) {
     195      203033 :     register int len = 0;
     196             : 
     197    12160828 :     while ( *str++!='\0' )
     198    11754762 :         ++len;
     199      203033 : return( len );
     200             : }
     201             : 
     202           0 : int c_strlen( const char * p )
     203             : {
     204           0 :     if(!p)
     205           0 :         return 0;
     206           0 :     return strlen(p);
     207             : }
     208             : 
     209             : 
     210           0 : unichar_t *u_strchr(const unichar_t *str ,unichar_t ch) {
     211             :     register unichar_t test;
     212             : 
     213           0 :     while ( (test=*(str++))!='\0' )
     214           0 :         if ( test==ch )
     215           0 : return( (unichar_t *) str-1 );
     216             : 
     217           0 : return( NULL );
     218             : }
     219             : 
     220           0 : unichar_t *u_strrchr(const unichar_t *str ,unichar_t ch) {
     221           0 :     register unichar_t test, *last = NULL;
     222             : 
     223           0 :     while ( (test=*(str++))!='\0' )
     224           0 :         if ( test==ch )
     225           0 :             last = (unichar_t *) str-1;
     226             : 
     227           0 : return( last );
     228             : }
     229             : 
     230           0 : unichar_t *uc_strstr(const unichar_t *longer, const char *substr) {
     231             :     long ch1, ch2;
     232             :     const unichar_t *lpt, *str1; const char *str2;
     233             : 
     234           0 :     for ( lpt=longer; *lpt!='\0'; ++lpt ) {
     235           0 :         str1 = lpt; str2 = substr;
     236             :         for (;;) {
     237           0 :             ch1 = *str1++; ch2 = *(unsigned char *) str2++ ;
     238           0 :             if ( ch2=='\0' )
     239           0 : return((unichar_t *) lpt);
     240           0 :             if ( ch1!=ch2 )
     241           0 :         break;
     242           0 :         }
     243             :     }
     244           0 : return( NULL );
     245             : }
     246             : 
     247           0 : unichar_t *u_strstr(const unichar_t *longer, const unichar_t *substr) {
     248             :     long ch1, ch2;
     249             :     const unichar_t *lpt, *str1, *str2;
     250             : 
     251           0 :     for ( lpt=longer; *lpt!='\0'; ++lpt ) {
     252           0 :         str1 = lpt; str2 = substr;
     253             :         for (;;) {
     254           0 :             ch1 = *str1++; ch2 = *str2++ ;
     255           0 :             if ( ch2=='\0' )
     256           0 : return((unichar_t *) lpt);
     257           0 :             if ( ch1!=ch2 )
     258           0 :         break;
     259           0 :         }
     260             :     }
     261           0 : return( NULL );
     262             : }
     263             : 
     264           0 : unichar_t *uc_strstrmatch(const unichar_t *longer, const char *substr) {
     265             :     long ch1, ch2;
     266             :     const unichar_t *lpt, *str1; const unsigned char *str2;
     267             : 
     268           0 :     for ( lpt=longer; *lpt!='\0'; ++lpt ) {
     269           0 :         str1 = lpt; str2 = (unsigned char *) substr;
     270             :         for (;;) {
     271           0 :             ch1 = *str1++; ch2 = *str2++ ;
     272           0 :             ch1 = tolower(ch1);
     273           0 :             ch2 = tolower(ch2);
     274           0 :             if ( ch2=='\0' )
     275           0 : return((unichar_t *) lpt);
     276           0 :             if ( ch1!=ch2 )
     277           0 :         break;
     278           0 :         }
     279             :     }
     280           0 : return( NULL );
     281             : }
     282             : 
     283           0 : unichar_t *u_strstrmatch(const unichar_t *longer, const unichar_t *substr) {
     284             :     long ch1, ch2;
     285             :     const unichar_t *lpt, *str1, *str2;
     286             : 
     287           0 :     for ( lpt=longer; *lpt!='\0'; ++lpt ) {
     288           0 :         str1 = lpt; str2 = substr;
     289             :         for (;;) {
     290           0 :             ch1 = *str1++; ch2 = *str2++ ;
     291           0 :             ch1 = tolower(ch1);
     292           0 :             ch2 = tolower(ch2);
     293           0 :             if ( ch2=='\0' )
     294           0 : return((unichar_t *) lpt);
     295           0 :             if ( ch1!=ch2 )
     296           0 :         break;
     297           0 :         }
     298             :     }
     299           0 : return( NULL );
     300             : }
     301             : 
     302           0 : unichar_t *u_copyn(const unichar_t *pt, long n) {
     303             :     unichar_t *res;
     304             : #ifdef MEMORY_MASK
     305             :     if ( n*sizeof(unichar_t)>=MEMORY_MASK )
     306             :         n = MEMORY_MASK/sizeof(unichar_t)-1;
     307             : #endif
     308           0 :     res = (unichar_t *) malloc((n+1)*sizeof(unichar_t));
     309           0 :     memcpy(res,pt,n*sizeof(unichar_t));
     310           0 :     res[n]='\0';
     311           0 : return(res);
     312             : }
     313             : 
     314           0 : unichar_t *u_copynallocm(const unichar_t *pt, long n, long m) {
     315             :     unichar_t *res;
     316             : #ifdef MEMORY_MASK
     317             :     if ( n*sizeof(unichar_t)>=MEMORY_MASK )
     318             :         n = MEMORY_MASK/sizeof(unichar_t)-1;
     319             : #endif
     320           0 :     res = malloc((m+1)*sizeof(unichar_t));
     321           0 :     memcpy(res,pt,n*sizeof(unichar_t));
     322           0 :     res[n]='\0';
     323           0 : return(res);
     324             : }
     325             : 
     326           0 : unichar_t *u_copy(const unichar_t *pt) {
     327           0 :     if(pt)
     328           0 : return u_copyn(pt,u_strlen(pt));
     329             : 
     330           0 : return((unichar_t *)0);
     331             : }
     332             : 
     333           0 : unichar_t *u_concat(const unichar_t *s1, const unichar_t *s2) {
     334             :     long len1, len2;
     335             :     unichar_t *pt;
     336             : 
     337           0 :     if ( s1==NULL )
     338           0 : return( u_copy( s2 ));
     339           0 :     else if ( s2==NULL )
     340           0 : return( u_copy( s1 ));
     341           0 :     len1 = u_strlen(s1); len2 = u_strlen(s2);
     342           0 :     pt = (unichar_t *) malloc((len1+len2+1)*sizeof(unichar_t));
     343           0 :     u_strcpy(pt,s1);
     344           0 :     u_strcpy(pt+len1,s2);
     345           0 : return( pt );
     346             : }
     347             : 
     348           0 : unichar_t *uc_copyn(const char *pt,int len) {
     349             :     unichar_t *res, *rpt;
     350             : 
     351           0 :     if(!pt)
     352           0 : return((unichar_t *)0);
     353             : 
     354             : #ifdef MEMORY_MASK
     355             :     if ( (len+1)*sizeof(unichar_t)>=MEMORY_MASK )
     356             :         len = MEMORY_MASK/sizeof(unichar_t)-1;
     357             : #endif
     358           0 :     res = (unichar_t *) malloc((len+1)*sizeof(unichar_t));
     359           0 :     for ( rpt=res; --len>=0 ; *rpt++ = *(unsigned char *) pt++ );
     360           0 :     *rpt = '\0';
     361           0 : return(res);
     362             : }
     363             : 
     364           3 : unichar_t *uc_copy(const char *pt) {
     365             :     unichar_t *res, *rpt;
     366             :     int n;
     367             : 
     368           3 :     if(!pt)
     369           0 : return((unichar_t *)0);
     370             : 
     371           3 :     n = strlen(pt);
     372             : #ifdef MEMORY_MASK
     373             :     if ( (n+1)*sizeof(unichar_t)>=MEMORY_MASK )
     374             :         n = MEMORY_MASK/sizeof(unichar_t)-1;
     375             : #endif
     376           3 :     res = (unichar_t *) malloc((n+1)*sizeof(unichar_t));
     377           3 :     for ( rpt=res; --n>=0 ; *rpt++ = *(unsigned char *) pt++ );
     378           3 :     *rpt = '\0';
     379           3 : return(res);
     380             : }
     381             : 
     382           0 : char *cu_copyn(const unichar_t *pt,int len) {
     383             :     char *res, *rpt;
     384             : 
     385           0 :     if(!pt)
     386           0 : return(NULL);
     387             : 
     388             : #ifdef MEMORY_MASK
     389             :     if ( (len+1)>=MEMORY_MASK )
     390             :         len = MEMORY_MASK-1;
     391             : #endif
     392           0 :     res = (char *) malloc(len+1);
     393           0 :     for ( rpt=res; --len>=0 ; *rpt++ = *pt++ );
     394           0 :     *rpt = '\0';
     395           0 : return(res);
     396             : }
     397             : 
     398           0 : char *cu_copy(const unichar_t *pt) {
     399             :     char *res, *rpt;
     400             :     int n;
     401             : 
     402           0 :     if(!pt)
     403           0 : return((char *)0);
     404             : 
     405           0 :     n = u_strlen(pt);
     406             : #ifdef MEMORY_MASK
     407             :     if ( (n+1)>=MEMORY_MASK )
     408             :         n = MEMORY_MASK/sizeof(unichar_t)-1;
     409             : #endif
     410           0 :     res = (char *) malloc(n+1);
     411           0 :     for ( rpt=res; --n>=0 ; *rpt++ = *pt++ );
     412           0 :     *rpt = '\0';
     413           0 : return(res);
     414             : }
     415             : 
     416           0 : double u_strtod(const unichar_t *str, unichar_t **ptr) {
     417             :     char buf[60], *pt, *ret;
     418             :     const unichar_t *upt;
     419             :     double val;
     420             : 
     421           0 :     for ( upt=str, pt=buf; *upt<128 && *upt!='\0' && pt-buf<(ptrdiff_t)(sizeof(buf)-1); )
     422           0 :         *pt++ = *upt++;
     423           0 :     *pt = '\0';
     424           0 :     val = strtod(buf,&ret);
     425           0 :     if ( ptr!=NULL ) {
     426           0 :         if ( pt==ret )
     427           0 :             *ptr = (unichar_t *) upt;
     428             :         else
     429           0 :             *ptr = (unichar_t *) (str + (ret-buf));
     430             :     }
     431           0 : return( val );
     432             : }
     433             : 
     434           0 : long u_strtol(const unichar_t *str, unichar_t **ptr, int base) {
     435             :     char buf[60], *pt, *ret;
     436             :     const unichar_t *upt;
     437             :     long val;
     438             : 
     439           0 :     for ( upt=str, pt=buf; *upt<128 && *upt!='\0' && pt<buf+sizeof(buf)-1; )
     440           0 :         *pt++ = *upt++;
     441           0 :     *pt = '\0';
     442           0 :     val = strtol(buf,&ret,base);
     443           0 :     if ( ptr!=NULL ) {
     444           0 :         if ( pt==ret )
     445           0 :             *ptr = (unichar_t *) upt;
     446             :         else
     447           0 :             *ptr = (unichar_t *) (str + (ret-buf));
     448             :     }
     449           0 : return( val );
     450             : }
     451             : 
     452           0 : unsigned long u_strtoul(const unichar_t *str, unichar_t **ptr, int base) {
     453             :     char buf[60], *pt, *ret;
     454             :     const unichar_t *upt;
     455             :     unsigned long val;
     456             : 
     457           0 :     for ( upt=str, pt=buf; *upt<128 && *upt!='\0' && pt<buf+sizeof(buf)-1; )
     458           0 :         *pt++ = *upt++;
     459           0 :     *pt = '\0';
     460           0 :     val = strtoul(buf,&ret,base);
     461           0 :     if ( ptr!=NULL ) {
     462           0 :         if ( pt==ret )
     463           0 :             *ptr = (unichar_t *) upt;
     464             :         else
     465           0 :             *ptr = (unichar_t *) (str + (ret-buf));
     466             :     }
     467           0 : return( val );
     468             : }
     469             : 
     470           0 : unichar_t *cu_strstartmatch(const char *key,const unichar_t *str) {
     471           0 :     if ( key && str ) {
     472           0 :         while( *key ) {
     473           0 :             if(tolower(*key) != tolower(*str))
     474           0 : return 0;
     475           0 :             key++;
     476           0 :             str++;
     477             :         }
     478             :     }
     479           0 : return (unichar_t *)str;
     480             : }
     481             : 
     482           0 : unichar_t *u_strstartmatch(const unichar_t *initial, const unichar_t *full) {
     483             :     int ch1, ch2;
     484             :     for (;;) {
     485           0 :         ch1 = *initial++; ch2 = *full++ ;
     486           0 :         if ( ch1=='\0' )
     487           0 : return( (unichar_t *) full );
     488           0 :         ch1 = tolower(ch1);
     489           0 :         ch2 = tolower(ch2);
     490           0 :         if ( ch1!=ch2 || ch1=='\0' )
     491           0 : return(NULL);
     492           0 :     }
     493             : }
     494             : 
     495           0 : char *u_to_c(const unichar_t *ubuf) {
     496           0 :     if( !ubuf )
     497           0 :         return 0;
     498             :     static char buf[400];
     499           0 :     cu_strncpy(buf,ubuf,sizeof(buf));
     500           0 : return( buf );
     501             : }
     502             : 
     503           0 : unichar_t *c_to_u(const char *buf) {
     504             :     static unichar_t ubuf[400];
     505           0 :     uc_strncpy(ubuf,buf,sizeof(ubuf));
     506           0 : return( ubuf );
     507             : }
     508             : 
     509      203460 : unichar_t *utf82u_strncpy(unichar_t *ubuf,const char *utf8buf,int len) {
     510      203460 :     unichar_t *upt=ubuf, *uend=ubuf+len-1;
     511      203460 :     const uint8 *pt = (const uint8 *) utf8buf, *end = pt+strlen(utf8buf);
     512             :     int w, w2;
     513             : 
     514    12172982 :     while ( pt<end && *pt!='\0' && upt<uend ) {
     515    11766062 :         if ( *pt<=127 )
     516    11764154 :             *upt = *pt++;
     517        1908 :         else if ( *pt<=0xdf ) {
     518        1892 :             *upt = ((*pt&0x1f)<<6) | (pt[1]&0x3f);
     519        1892 :             pt += 2;
     520          16 :         } else if ( *pt<=0xef ) {
     521          16 :             *upt = ((*pt&0xf)<<12) | ((pt[1]&0x3f)<<6) | (pt[2]&0x3f);
     522          16 :             pt += 3;
     523             :         } else {
     524           0 :             w = ( ((*pt&0x7)<<2) | ((pt[1]&0x30)>>4) )-1;
     525           0 :             w = (w<<6) | ((pt[1]&0xf)<<2) | ((pt[2]&0x30)>>4);
     526           0 :             w2 = ((pt[2]&0xf)<<6) | (pt[3]&0x3f);
     527           0 :             *upt = w*0x400 + w2 + 0x10000;
     528           0 :             pt += 4;
     529             :         }
     530    11766062 :         ++upt;
     531             :     }
     532      203460 :     *upt = '\0';
     533      203460 : return( ubuf );
     534             : }
     535             : 
     536           0 : unichar_t *utf82u_strcpy(unichar_t *ubuf,const char *utf8buf) {
     537           0 : return( utf82u_strncpy(ubuf,utf8buf,strlen(utf8buf)+1));
     538             : }
     539             : 
     540           0 : unichar_t *utf82u_copyn(const char *utf8buf,int len) {
     541           0 :     unichar_t *ubuf = (unichar_t *) malloc((len+1)*sizeof(unichar_t));
     542           0 : return( utf82u_strncpy(ubuf,utf8buf,len+1));
     543             : }
     544             : 
     545      203480 : unichar_t *utf82u_copy(const char *utf8buf) {
     546             :     int len;
     547             :     unichar_t *ubuf;
     548             : 
     549      203480 :     if ( utf8buf==NULL )
     550          20 : return( NULL );
     551             : 
     552      203460 :     len = strlen(utf8buf);
     553      203460 :     ubuf = (unichar_t *) malloc((len+1)*sizeof(unichar_t));
     554      203460 : return( utf82u_strncpy(ubuf,utf8buf,len+1));
     555             : }
     556             : 
     557           0 : void utf82u_strcat(unichar_t *to,const char *from) {
     558           0 :     utf82u_strcpy(to+u_strlen(to),from);
     559           0 : }
     560             : 
     561           0 : char *u2utf8_strcpy(char *utf8buf,const unichar_t *ubuf) {
     562             : /* Copy unichar string 'ubuf' into utf8 buffer string 'utf8buf' */
     563           0 :     char *pt = utf8buf;
     564             : 
     565           0 :     if ( ubuf!=NULL ) {
     566           0 :         while ( *ubuf && (pt=utf8_idpb(pt,*ubuf++,0)) );
     567           0 :         if ( pt ) {
     568           0 :             *pt = '\0';
     569           0 :             return( utf8buf );
     570             :         }
     571             :     }
     572           0 :     return( NULL );
     573             : }
     574             : 
     575           0 : char *utf8_strchr(const char *str, int search) {
     576             :     int ch;
     577           0 :     const char *old = str;
     578             : 
     579           0 :     while ( (ch = utf8_ildb(&str))!=0 ) {
     580           0 :         if ( ch==search )
     581           0 : return( (char *) old );
     582           0 :         old = str;
     583             :     }
     584           0 : return( NULL );
     585             : }
     586             : 
     587          15 : char *latin1_2_utf8_strcpy(char *utf8buf,const char *lbuf) {
     588          15 :     char *pt = utf8buf;
     589          15 :     const unsigned char *lpt = (const unsigned char *) lbuf;
     590             : 
     591         511 :     while ( *lpt ) {
     592         481 :         if ( *lpt<0x80 )
     593         478 :             *pt++ = *lpt;
     594             :         else {
     595           3 :             *pt++ = 0xc0 | (*lpt>>6);
     596           3 :             *pt++ = 0x80 | (*lpt&0x3f);
     597             :         }
     598         481 :         ++lpt;
     599             :     }
     600          15 :     *pt = '\0';
     601          15 : return( utf8buf );
     602             : }
     603             : 
     604          15 : char *latin1_2_utf8_copy(const char *lbuf) {
     605             :     int len;
     606             :     char *utf8buf;
     607             : 
     608          15 :     if ( lbuf==NULL )
     609           0 : return( NULL );
     610             : 
     611          15 :     len = strlen(lbuf);
     612          15 :     utf8buf = (char *) malloc(2*len+1);
     613          15 : return( latin1_2_utf8_strcpy(utf8buf,lbuf));
     614             : }
     615             : 
     616           0 : char *utf8_2_latin1_copy(const char *utf8buf) {
     617             :     int len;
     618             :     int ch;
     619             :     char *lbuf, *pt; const char *upt;
     620             : 
     621           0 :     if ( utf8buf==NULL )
     622           0 : return( NULL );
     623             : 
     624           0 :     len = strlen(utf8buf);
     625           0 :     pt = lbuf = (char *) malloc(len+1);
     626           0 :     for ( upt=utf8buf; (ch=utf8_ildb(&upt))!='\0'; )
     627           0 :         if ( ch>=0xff )
     628           0 :             *pt++ = '?';
     629             :         else
     630           0 :             *pt++ = ch;
     631           0 :     *pt = '\0';
     632           0 : return( lbuf );
     633             : }
     634             : 
     635         637 : char *u2utf8_copy(const unichar_t *ubuf) {
     636             : /* Make a utf8 string copy of unichar string ubuf */
     637             : 
     638         637 :     if ( ubuf==NULL )
     639           0 :         return( NULL );
     640             : 
     641         637 :     return( u2utf8_copyn(ubuf,u_strlen(ubuf)+1) );
     642             : }
     643             : 
     644         637 : char *u2utf8_copyn(const unichar_t *ubuf,int len) {
     645             : /* Make a utf8 string copy of unichar string ubuf[0..len] */
     646             :     char *utf8buf, *pt;
     647             : 
     648         637 :     if ( ubuf==NULL || len<=0 || (utf8buf=pt=(char *)malloc(len*6+1))==NULL )
     649           0 :         return( NULL );
     650             : 
     651         637 :     while ( (pt=utf8_idpb(pt,*ubuf++,0)) && --len );
     652         637 :     if ( pt ) {
     653         637 :         *pt = '\0';
     654         637 :         return( utf8buf );
     655             :     }
     656           0 :     free( utf8buf );
     657           0 :     return( NULL );
     658             : }
     659             : 
     660       63376 : int32 utf8_ildb(const char **_text) {
     661       63376 :     int32 val= -1;
     662             :     int ch;
     663       63376 :     const uint8 *text = (const uint8 *) *_text;
     664             :     /* Increment and load character */
     665             : 
     666       63376 :     if ( text==NULL )
     667           0 :         return( val );
     668       63376 :     else if ( (ch = *text++)<0x80 ) {
     669       61313 :         val = ch;
     670        2063 :     } else if ( ch<=0xbf ) {
     671             :         /* error */
     672        2061 :     } else if ( ch<=0xdf ) {
     673        2026 :         if ( *text>=0x80 && *text<0xc0 )
     674        2026 :             val = ((ch&0x1f)<<6) | (*text++&0x3f);
     675          35 :     } else if ( ch<=0xef ) {
     676          34 :         if ( *text>=0x80 && *text<0xc0 && text[1]>=0x80 && text[1]<0xc0 ) {
     677          34 :             val = ((ch&0xf)<<12) | ((text[0]&0x3f)<<6) | (text[1]&0x3f);
     678          34 :             text += 2;
     679             :         }
     680             :     } else {
     681           1 :         int w = ( ((ch&0x7)<<2) | ((text[0]&0x30)>>4) )-1, w2;
     682           1 :         w = (w<<6) | ((text[0]&0xf)<<2) | ((text[1]&0x30)>>4);
     683           1 :         w2 = ((text[1]&0xf)<<6) | (text[2]&0x3f);
     684           1 :         val = w*0x400 + w2 + 0x10000;
     685           1 :         if ( *text<0x80 || text[1]<0x80 || text[2]<0x80 ||
     686           0 :                 *text>=0xc0 || text[1]>=0xc0 || text[2]>=0xc0 )
     687           1 :             val = -1;
     688             :         else
     689           0 :             text += 3;
     690             :     }
     691       63376 :     *_text = (const char *) text;
     692       63376 : return( val );
     693             : }
     694             : 
     695       74896 : char *utf8_idpb(char *utf8_text,uint32 ch,int flags) {
     696             : /* Increment and deposit character, no '\0' appended */
     697             : /* NOTE: Unicode only needs range of 17x65535 values */
     698             : /* and strings must be long enough to hold +4 chars. */
     699             : /* ISO/IEC 10646 description of UTF8 allows encoding */
     700             : /* character values up to U+7FFFFFFF before RFC3629. */
     701             : 
     702      149792 :     if ( ch>0x7fffffff || \
     703      149792 :          (!(flags&UTF8IDPB_OLDLIMIT) && ((ch>=0xd800 && ch<=0xdfff) || ch>=17*65536)) )
     704           0 :         return( 0 ); /* Error, ch is out of range */
     705             : 
     706       74896 :     if ( (flags&(UTF8IDPB_UCS2|UTF8IDPB_UTF16|UTF8IDPB_UTF32)) ) {
     707           0 :         if ( (flags&UTF8IDPB_UCS2) && ch>0xffff )
     708           0 :             return( 0 ); /* Error, ch is out of range */
     709           0 :         if ( (flags&UTF8IDPB_UTF32) ) {
     710           0 :             *utf8_text++ = ((ch>>24)&0xff);
     711           0 :             *utf8_text++ = ((ch>>16)&0xff);
     712           0 :             ch &= 0xffff;
     713             :         }
     714           0 :         if ( ch>0xffff ) {
     715             :             /* ...here if a utf16 encoded value */
     716             :             unsigned long us;
     717           0 :             ch -= 0x10000;
     718           0 :             us = (ch>>10)+0xd800;
     719           0 :             *utf8_text++ = us>>8;
     720           0 :             *utf8_text++ = us&0xff;
     721           0 :             ch = (ch&0x3ff)+0xdc00;
     722             :         }
     723           0 :         *utf8_text++ = ch>>8;
     724           0 :         ch &= 0xff;
     725       74896 :     } else if ( ch>127 || (ch==0 && (flags&UTF8IDPB_NOZERO)) ) {
     726        3724 :         if ( ch<=0x7ff )
     727             :             /* ch>=0x80 && ch<=0x7ff */
     728        3692 :             *utf8_text++ = 0xc0 | (ch>>6);
     729             :         else {
     730          32 :             if ( ch<=0xffff )
     731             :                 /* ch>=0x800 && ch<=0xffff */
     732          32 :                 *utf8_text++ = 0xe0 | (ch>>12);
     733             :             else {
     734           0 :                 if ( ch<=0x1fffff )
     735             :                     /* ch>=0x10000 && ch<=0x1fffff */
     736           0 :                     *utf8_text++ = 0xf0 | (ch>>18);
     737             :                 else {
     738           0 :                     if ( ch<=0x3ffffff )
     739             :                         /* ch>=0x200000 && ch<=0x3ffffff */
     740           0 :                         *utf8_text++ = 0xf8 | (ch>>24);
     741             :                     else {
     742             :                         /* ch>=0x4000000 && ch<=0x7fffffff */
     743           0 :                         *utf8_text++ = 0xfc | (ch>>30);
     744           0 :                         *utf8_text++ = 0x80 | ((ch>>24)&0x3f);
     745             :                     }
     746           0 :                     *utf8_text++ = 0x80 | ((ch>>18)&0x3f);
     747             :                 }
     748           0 :                 *utf8_text++ = 0x80 | ((ch>>12)&0x3f);
     749             :             }
     750          32 :             *utf8_text++ = 0x80 | ((ch>>6)&0x3f);
     751             :         }
     752        3724 :         ch = 0x80 | (ch&0x3f);
     753             :     }
     754       74896 :     *utf8_text++ = ch;
     755       74896 :     return( utf8_text );
     756             : }
     757             : 
     758           0 : char *utf8_ib(char *utf8_text) {
     759             : /* Increment to next utf8 character */
     760             :     unsigned char ch;
     761             : 
     762           0 :     if ( (ch = (unsigned char) *utf8_text)=='\0' )
     763           0 :         return( utf8_text );
     764           0 :     else if ( ch<=127 )
     765           0 :         return( utf8_text+1 );
     766           0 :     else if ( ch<0xe0 )
     767           0 :         return( utf8_text+2 );
     768           0 :     else if ( ch<0xf0 )
     769           0 :         return( utf8_text+3 );
     770           0 :     else if ( ch<0xf8 )
     771           0 :         return( utf8_text+4 );
     772           0 :     else if ( ch<0xfc )
     773           0 :         return( utf8_text+5 );
     774             :     else
     775           0 :         return( utf8_text+6 );
     776             : }
     777             : 
     778         279 : int utf8_valid(const char *str) {
     779             :     /* Is this a valid utf8 string? */
     780             :     int ch;
     781             : 
     782        9641 :     while ( (ch=utf8_ildb(&str))!='\0' )
     783        9086 :         if ( ch==-1 )
     784           3 : return( false );
     785             : 
     786         276 : return( true );
     787             : }
     788             : 
     789           0 : void utf8_truncatevalid(char *str) {
     790             :     /* There are certain cases where we have a fixed amount of space to display */
     791             :     /*  something, and if it doesn't fit in that, then we truncate it. But... */
     792             :     /*  that can leave us with a half completed utf8 byte sequence. So truncate*/
     793             :     /*  again, right before the start of the bad sequence */
     794             :     int ch;
     795             :     char *old;
     796             : 
     797           0 :     old = str;
     798           0 :     while ( (ch=utf8_ildb((const char **) &str))!='\0' ) {
     799           0 :         if ( ch==-1 ) {
     800           0 :             *old = '\0';
     801           0 : return;
     802             :         }
     803           0 :         old = str;
     804             :     }
     805             : }
     806             : 
     807           0 : char *utf8_db(char *utf8_text) {
     808             : /* Decrement utf8 pointer to previous utf8 character.*/
     809             : /* NOTE: This should never happen but if the pointer */
     810             : /* was looking at an intermediate character, it will */
     811             : /* be properly positioned at the start of a new char */
     812             : /* and not the previous character.                   */
     813           0 :     unsigned char *pt = (unsigned char *) utf8_text;
     814             : 
     815           0 :     --pt;
     816           0 :     if ( *pt>=0x80 && *pt<0xc0 ) {
     817           0 :         --pt;
     818           0 :         if ( *pt>=0x80 && *pt<0xc0 ) {
     819           0 :             --pt;
     820           0 :             if ( *pt>=0x80 && *pt<0xc0 ) {
     821           0 :                 --pt;
     822           0 :                 if ( *pt>=0x80 && *pt<0xc0 ) {
     823           0 :                     --pt;
     824           0 :                     if ( *pt>=0x80 && *pt<0xc0 )
     825           0 :                         --pt;
     826             :                 }
     827             :             }
     828             :         }
     829             :     }
     830           0 :     return( (char *) pt );
     831             : }
     832             : 
     833           0 : long utf8_strlen(const char *utf8_str) {
     834             : /* Count how many characters in the string NOT bytes */
     835           0 :     long len = 0;
     836             : 
     837           0 :     while ( utf8_ildb(&utf8_str)>0 && ++len>0 );
     838           0 :     return( len );
     839             : }
     840             : 
     841         480 : long utf82u_strlen(const char *utf8_str) {
     842             : /* Count how many shorts needed to represent in UCS2 */
     843             :     int32 ch;
     844         480 :     long len = 0;
     845             : 
     846       28812 :     while ( (ch = utf8_ildb(&utf8_str))>0 && ++len>0 )
     847       27852 :         if ( ch>=0x10000 )
     848           0 :             ++len;
     849         480 :     return( len );
     850             : }
     851             : 
     852           0 : void utf8_strncpy(register char *to, const char *from, int len) {
     853             :     /* copy n characters NOT bytes */
     854           0 :     const char *old = from;
     855           0 :     while ( len && *old ) {
     856           0 :         utf8_ildb(&old);
     857           0 :         len--;
     858             :     }
     859           0 :     strncpy(to, from, old-from);
     860           0 :     to[old-from] = 0;
     861           0 : }
     862             : 
     863             : #include <chardata.h>
     864           4 : char *StripToASCII(const char *utf8_str) {
     865             :     /* Remove any non-ascii characters: Special case, convert the copyright symbol to (c) */
     866             :     char *newcr, *pt, *end;
     867             :     int len, ch;
     868             :     const unichar_t *alt;
     869             : 
     870           4 :     len = strlen(utf8_str);
     871           4 :     pt = newcr = (char *) malloc(len+1);
     872           4 :     end = pt+len;
     873         181 :     while ( (ch= utf8_ildb(&utf8_str))!='\0' ) {
     874         173 :         if ( pt>=end ) {
     875           4 :             int off = pt-newcr;
     876           4 :             newcr = (char *) realloc(newcr,(off+10)+1);
     877           4 :             pt = newcr+off;
     878           4 :             end = pt+10;
     879             :         }
     880         173 :         if ( (ch>=' ' && ch<'\177' ) || ch=='\n' || ch=='\t' )
     881         169 :             *pt++ = ch;
     882           4 :         else if ( ch=='\r' && *utf8_str!='\n' )
     883           0 :             *pt++ = '\n';
     884           4 :         else if ( ch==0xa9 /* Copyright sign */ ) {
     885           4 :             const char *str = "(c)";
     886           4 :             if ( pt+strlen(str)>=end ) {
     887           0 :                 int off = pt-newcr;
     888           0 :                 newcr = (char *) realloc(newcr,(off+10+strlen(str))+1);
     889           0 :                 pt = newcr+off;
     890           0 :                 end = pt+10;
     891             :             }
     892          20 :             while ( *str )
     893          12 :                 *pt++ = *str++;
     894           0 :         } else if ( unicode_alternates[ch>>8]!=NULL &&
     895           0 :                 (alt = unicode_alternates[ch>>8][ch&0xff])!=NULL ) {
     896           0 :             while ( *alt!='\0' ) {
     897           0 :                 if ( pt>=end ) {
     898           0 :                     int off = pt-newcr;
     899           0 :                     newcr = (char *) realloc(newcr,(off+10)+1);
     900           0 :                     pt = newcr+off;
     901           0 :                     end = pt+10;
     902             :                 }
     903           0 :                 if ( *alt>=' ' && *alt<'\177' )
     904           0 :                     *pt++ = *alt;
     905           0 :                 else if ( *alt==0x300 )
     906           0 :                     *pt++ = '`';
     907           0 :                 else if ( *alt==0x301 )
     908           0 :                     *pt++ = '\'';
     909           0 :                 else if ( *alt==0x302 )
     910           0 :                     *pt++ = '^';
     911           0 :                 else if ( *alt==0x303 )
     912           0 :                     *pt++ = '~';
     913           0 :                 else if ( *alt==0x308 )
     914           0 :                     *pt++ = ':';
     915           0 :                 ++alt;
     916             :             }
     917             :         }
     918             :     }
     919           4 :     *pt = '\0';
     920           4 : return( newcr );
     921             : }
     922             : 
     923        2477 : int AllAscii(const char *txt) {
     924       23574 :     for ( ; *txt!='\0'; ++txt ) {
     925       21101 :         if ( *txt=='\t' || *txt=='\n' || *txt=='\r' )
     926             :             /* All right */;
     927       21094 :         else if ( *txt<' ' || *txt>='\177' )
     928           4 : return( false );
     929             :     }
     930        2473 : return( true );
     931             : }
     932             : 
     933           0 : int uAllAscii(const unichar_t *txt) {
     934           0 :     for ( ; *txt!='\0'; ++txt ) {
     935           0 :         if ( *txt=='\t' || *txt=='\n' || *txt=='\r' )
     936             :             /* All right */;
     937           0 :         else if ( *txt<' ' || *txt>='\177' )
     938           0 : return( false );
     939             :     }
     940           0 : return( true );
     941             : }
     942             : 
     943           0 : char* chomp( char* line ) {
     944           0 :     if( !line )
     945           0 :         return line;
     946           0 :     if ( line[strlen(line)-1]=='\n' )
     947           0 :         line[strlen(line)-1] = '\0';
     948           0 :     if ( line[strlen(line)-1]=='\r' )
     949           0 :         line[strlen(line)-1] = '\0';
     950           0 :     return line;
     951             : }
     952             : 
     953           0 : char *copytolower(const char *input)
     954             : {
     955           0 :     char* ret = copy(input);
     956           0 :     char* p = ret;
     957           0 :     for( ; *p; ++p ) {
     958           0 :         *p = tolower(*p);
     959             :     }
     960           0 :     return ret;
     961             : }
     962             : 
     963             : 
     964           0 : int endswith(const char *haystack,const char *needle) {
     965           0 :     int haylen = strlen( haystack );
     966           0 :     int nedlen = strlen( needle );
     967           0 :     if( haylen < nedlen )
     968           0 :         return 0;
     969           0 :     char* p = strstr( haystack + haylen - nedlen, needle );
     970           0 :     return p == ( haystack + haylen - nedlen );
     971             : }
     972             : 
     973           0 : int endswithi(const char *haystackZ,const char *needleZ) {
     974           0 :     char* haystack = copytolower(haystackZ);
     975           0 :     char* needle   = copytolower(needleZ);
     976           0 :     int ret = endswith( haystack, needle );
     977           0 :     free( haystack );
     978           0 :     free( needle );
     979           0 :     return ret;
     980             : }
     981             : 
     982           0 : int endswithi_partialExtension( const char *haystackZ,const char *needleZ) {
     983           0 :     int nedlen = strlen(needleZ);
     984           0 :     if( nedlen == 0 ) {
     985           0 :         return 0;
     986             :     }
     987           0 :     char* haystack = copytolower(haystackZ);
     988           0 :     char* needle   = copytolower(needleZ);
     989           0 :     int ret = 0;
     990           0 :     int i = nedlen-1;
     991           0 :     ret |= endswith( haystack, needle );
     992           0 :     for( ; i>=0 && !ret ; --i ) {
     993           0 :         needle[i] = '\0';
     994           0 :         ret |= endswith( haystack, needle );
     995             :     }
     996           0 :     free( haystack );
     997           0 :     free( needle );
     998           0 :     return ret;
     999             : }
    1000             : 
    1001           0 : int u_endswith(const unichar_t *haystack,const unichar_t *needle) {
    1002           0 :     int haylen = u_strlen( haystack );
    1003           0 :     int nedlen = u_strlen( needle );
    1004           0 :     if( haylen < nedlen )
    1005           0 :         return 0;
    1006           0 :     unichar_t* p = u_strstr( haystack + haylen - nedlen, needle );
    1007           0 :     return p == ( haystack + haylen - nedlen );
    1008             : }
    1009             : 
    1010           0 : int u_startswith(const unichar_t *haystack,const unichar_t *needle) {
    1011             : 
    1012           0 :     if( !haystack || !needle )
    1013           0 :         return 0;
    1014             : 
    1015           0 :     unichar_t* p = u_strstr( haystack, needle );
    1016           0 :     return p == ( haystack );
    1017             : }
    1018             : 
    1019           0 : int uc_startswith(const unichar_t *haystack,const char* needle)
    1020             : {
    1021           0 :     return u_startswith( haystack, c_to_u(needle));
    1022             : }
    1023             : 
    1024             : 
    1025           0 : char* c_itostr( int v )
    1026             : {
    1027             :     static char ret[100+1];
    1028           0 :     snprintf(ret,100,"%d",v );
    1029           0 :     return ret;
    1030             : }
    1031             : 
    1032           0 : char* str_replace_all( char* s, char* orig, char* replacement, int free_s )
    1033             : {
    1034           0 :     char* p = strstr( s, orig );
    1035           0 :     if( !p )
    1036             :     {
    1037           0 :         if( free_s )
    1038           0 :             return s;
    1039           0 :         return copy( s );
    1040             :     }
    1041             : 
    1042           0 :     int count = 0;
    1043           0 :     p = s;
    1044           0 :     while( p )
    1045             :     {
    1046           0 :         p = strstr( p, orig );
    1047           0 :         if( !p )
    1048           0 :             break;
    1049           0 :         p++;
    1050           0 :         count++;
    1051             :     }
    1052           0 :     count++;
    1053             : 
    1054             :     // more than strictly needed, but always enough RAM.
    1055           0 :     int retsz = strlen(s) + count*strlen(replacement) + 1;
    1056           0 :     char* ret = (char *) malloc( retsz );
    1057           0 :     memset( ret, '\0', retsz );
    1058           0 :     char* output = ret;
    1059           0 :     char* remains = s;
    1060           0 :     p = remains;
    1061           0 :     while( p )
    1062             :     {
    1063           0 :         p = strstr( remains, orig );
    1064           0 :         if( !p )
    1065             :         {
    1066           0 :             strcpy( output, remains );
    1067           0 :             break;
    1068             :         }
    1069           0 :         if( p > remains )
    1070           0 :             strncpy( output, remains, p-remains );
    1071           0 :         strcat( output, replacement );
    1072           0 :         output += strlen(output);
    1073           0 :         remains = p + strlen(orig);
    1074             :     }
    1075             : 
    1076           0 :     if( free_s )
    1077           0 :         free(s);
    1078           0 :     return ret;
    1079             : }
    1080             : 
    1081           0 : int toint( char* v )
    1082             : {
    1083           0 :     if( !v )
    1084           0 :         return 0;
    1085           0 :     return atoi(v);
    1086             : }
    1087           0 : char* tostr( int v )
    1088             : {
    1089           0 :     const int bufsz = 100;
    1090             :     static char buf[101];
    1091           0 :     snprintf(buf,bufsz,"%d",v);
    1092           0 :     return buf;
    1093             : }

Generated by: LCOV version 1.10