VirtualBox

Changeset 51 in kBuild for trunk/src/kmk/str.c


Ignore:
Timestamp:
Apr 7, 2003 1:30:32 AM (22 years ago)
Author:
bird
Message:

kMk and porting to kLib.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/str.c

    r35 r51  
    11/*-
    22 * Copyright (c) 1988, 1989, 1990, 1993
    3  *      The Regents of the University of California.  All rights reserved.
     3 *      The Regents of the University of California.  All rights reserved.
    44 * Copyright (c) 1989 by Berkeley Softworks
    55 * All rights reserved.
     
    1818 * 3. All advertising materials mentioning features or use of this software
    1919 *    must display the following acknowledgement:
    20  *      This product includes software developed by the University of
    21  *      California, Berkeley and its contributors.
     20 *      This product includes software developed by the University of
     21 *      California, Berkeley and its contributors.
    2222 * 4. Neither the name of the University nor the names of its contributors
    2323 *    may be used to endorse or promote products derived from this software
     
    3939#ifndef lint
    4040#if 0
    41 static char sccsid[] = "@(#)str.c       5.8 (Berkeley) 6/1/90";
     41static char sccsid[] = "@(#)str.c       5.8 (Berkeley) 6/1/90";
    4242#else
    4343static const char rcsid[] =
    4444  "$FreeBSD: src/usr.bin/make/str.c,v 1.12.2.1 2002/06/17 04:30:48 jmallett Exp $";
    4545#endif
     46#define KLIBFILEDEF rcsid
    4647#endif /* not lint */
    4748
     
    5354/*
    5455 * str_init --
    55  *      Initialize the strings package
     56 *      Initialize the strings package
    5657 *
    5758 */
     
    6768/*
    6869 * str_end --
    69  *      Cleanup the strings package
     70 *      Cleanup the strings package
    7071 *
    7172 */
     
    7475{
    7576    if (argv) {
    76         if (argv[0])
    77             efree(argv[0]);
    78         efree((Address) argv);
     77        if (argv[0])
     78            efree(argv[0]);
     79        efree((Address) argv);
    7980    }
    8081    if (buffer)
    81         efree(buffer);
     82        efree(buffer);
    8283}
    8384
    8485/*-
    8586 * str_concat --
    86  *      concatenate the two strings, inserting a space or slash between them,
    87  *      freeing them if requested.
     87 *      concatenate the two strings, inserting a space or slash between them,
     88 *      freeing them if requested.
    8889 *
    8990 * returns --
    90  *      the resulting string in allocated space.
     91 *      the resulting string in allocated space.
    9192 */
    9293char *
    9394str_concat(s1, s2, flags)
    94         char *s1, *s2;
    95         int flags;
    96 {
    97         register int len1, len2;
    98         register char *result;
    99 
    100         /* get the length of both strings */
    101         len1 = strlen(s1);
    102         len2 = strlen(s2);
    103 
    104         /* allocate length plus separator plus EOS */
    105         result = emalloc((u_int)(len1 + len2 + 2));
    106 
    107         /* copy first string into place */
    108         memcpy(result, s1, len1);
    109 
    110         /* add separator character */
    111         if (flags & STR_ADDSPACE) {
    112                 result[len1] = ' ';
    113                 ++len1;
    114         } else if (flags & STR_ADDSLASH) {
    115                 result[len1] = '/';
    116                 ++len1;
    117         }
    118 
    119         /* copy second string plus EOS into place */
    120         memcpy(result + len1, s2, len2 + 1);
    121 
    122         /* efree original strings */
    123         if (flags & STR_DOFREE) {
    124                 (void)efree(s1);
    125                 (void)efree(s2);
    126         }
    127         return(result);
     95        char *s1, *s2;
     96        int flags;
     97{
     98        register int len1, len2;
     99        register char *result;
     100
     101        /* get the length of both strings */
     102        len1 = strlen(s1);
     103        len2 = strlen(s2);
     104
     105        /* allocate length plus separator plus EOS */
     106        result = emalloc((u_int)(len1 + len2 + 2));
     107
     108        /* copy first string into place */
     109        memcpy(result, s1, len1);
     110
     111        /* add separator character */
     112        if (flags & STR_ADDSPACE) {
     113                result[len1] = ' ';
     114                ++len1;
     115        } else if (flags & STR_ADDSLASH) {
     116                result[len1] = '/';
     117                ++len1;
     118        }
     119
     120        /* copy second string plus EOS into place */
     121        memcpy(result + len1, s2, len2 + 1);
     122
     123        /* efree original strings */
     124        if (flags & STR_DOFREE) {
     125                (void)efree(s1);
     126                (void)efree(s2);
     127        }
     128        return(result);
    128129}
    129130
    130131/*-
    131132 * brk_string --
    132  *      Fracture a string into an array of words (as delineated by tabs or
    133  *      spaces) taking quotation marks into account.  Leading tabs/spaces
    134  *      are ignored.
     133 *      Fracture a string into an array of words (as delineated by tabs or
     134 *      spaces) taking quotation marks into account.  Leading tabs/spaces
     135 *      are ignored.
    135136 *
    136137 * returns --
    137  *      Pointer to the array of pointers to the words.  To make life easier,
    138  *      the first word is always the value of the .MAKE variable.
     138 *      Pointer to the array of pointers to the words.  To make life easier,
     139 *      the first word is always the value of the .MAKE variable.
    139140 */
    140141char **
    141142brk_string(str, store_argc, expand)
    142         register char *str;
    143         int *store_argc;
    144         Boolean expand;
    145 {
    146         register int argc, ch;
    147         register char inquote, *p, *start, *t;
    148         int len;
    149 
    150         /* skip leading space chars. */
    151         for (; *str == ' ' || *str == '\t'; ++str)
    152                 continue;
    153 
    154         /* allocate room for a copy of the string */
    155         if ((len = strlen(str) + 1) > curlen) {
    156                 if (buffer)
    157                     efree(buffer);
    158                 buffer = emalloc(curlen = len);
    159         }
    160 
    161         /*
    162         * copy the string; at the same time, parse backslashes,
    163         * quotes and build the argument list.
    164         */
    165         argc = 1;
    166         inquote = '\0';
    167         for (p = str, start = t = buffer;; ++p) {
    168                 switch(ch = *p) {
    169                 case '"':
    170                 case '\'':
    171                         if (inquote) {
    172                                 if (inquote == ch)
    173                                         inquote = '\0';
    174                                 else
    175                                         break;
    176                         } else {
    177                                 inquote = (char) ch;
    178                                 /* Don't miss "" or '' */
    179                                 if (start == NULL && p[1] == inquote) {
    180                                         start = t + 1;
    181                                         break;
    182                                 }
    183                         }
    184                         if (!expand) {
    185                                 if (!start)
    186                                         start = t;
    187                                 *t++ = ch;
    188                         }
    189                         continue;
    190                 case ' ':
    191                 case '\t':
    192                 case '\n':
    193                         if (inquote)
    194                                 break;
    195                         if (!start)
    196                                 continue;
    197                         /* FALLTHROUGH */
    198                 case '\0':
    199                         /*
    200                         * end of a token -- make sure there's enough argv
    201                         * space and save off a pointer.
    202                         */
    203                         if (!start)
    204                             goto done;
    205 
    206                         *t++ = '\0';
    207                         if (argc == argmax) {
    208                                 argmax *= 2;            /* ramp up fast */
    209                                 argv = (char **)erealloc(argv,
    210                                     (argmax + 1) * sizeof(char *));
    211                         }
    212                         argv[argc++] = start;
    213                         start = (char *)NULL;
    214                         if (ch == '\n' || ch == '\0')
    215                                 goto done;
    216                         continue;
    217                 case '\\':
    218                         if (!expand) {
    219                                 if (!start)
    220                                         start = t;
    221                                 *t++ = '\\';
    222                                 ch = *++p;
    223                                 break;
    224                         }
    225 
    226                         switch (ch = *++p) {
    227                         case '\0':
    228                         case '\n':
    229                                 /* hmmm; fix it up as best we can */
    230                                 ch = '\\';
    231                                 --p;
    232                                 break;
    233                         case 'b':
    234                                 ch = '\b';
    235                                 break;
    236                         case 'f':
    237                                 ch = '\f';
    238                                 break;
    239                         case 'n':
    240                                 ch = '\n';
    241                                 break;
    242                         case 'r':
    243                                 ch = '\r';
    244                                 break;
    245                         case 't':
    246                                 ch = '\t';
    247                                 break;
    248                         }
    249                         break;
    250                 }
    251                 if (!start)
    252                         start = t;
    253                 *t++ = (char) ch;
    254         }
    255 done:   argv[argc] = (char *)NULL;
    256         *store_argc = argc;
    257         return(argv);
     143        register char *str;
     144        int *store_argc;
     145        Boolean expand;
     146{
     147        register int argc, ch;
     148        register char inquote, *p, *start, *t;
     149        int len;
     150
     151        /* skip leading space chars. */
     152        for (; *str == ' ' || *str == '\t'; ++str)
     153                continue;
     154
     155        /* allocate room for a copy of the string */
     156        if ((len = strlen(str) + 1) > curlen) {
     157                if (buffer)
     158                    efree(buffer);
     159                buffer = emalloc(curlen = len);
     160        }
     161
     162        /*
     163        * copy the string; at the same time, parse backslashes,
     164        * quotes and build the argument list.
     165        */
     166        argc = 1;
     167        inquote = '\0';
     168        for (p = str, start = t = buffer;; ++p) {
     169                switch(ch = *p) {
     170                case '"':
     171                case '\'':
     172                        if (inquote) {
     173                                if (inquote == ch)
     174                                        inquote = '\0';
     175                                else
     176                                        break;
     177                        } else {
     178                                inquote = (char) ch;
     179                                /* Don't miss "" or '' */
     180                                if (start == NULL && p[1] == inquote) {
     181                                        start = t + 1;
     182                                        break;
     183                                }
     184                        }
     185                        if (!expand) {
     186                                if (!start)
     187                                        start = t;
     188                                *t++ = ch;
     189                        }
     190                        continue;
     191                case ' ':
     192                case '\t':
     193                case '\n':
     194                        if (inquote)
     195                                break;
     196                        if (!start)
     197                                continue;
     198                        /* FALLTHROUGH */
     199                case '\0':
     200                        /*
     201                        * end of a token -- make sure there's enough argv
     202                        * space and save off a pointer.
     203                        */
     204                        if (!start)
     205                            goto done;
     206
     207                        *t++ = '\0';
     208                        if (argc == argmax) {
     209                                argmax *= 2;            /* ramp up fast */
     210                                argv = (char **)erealloc(argv,
     211                                    (argmax + 1) * sizeof(char *));
     212                        }
     213                        argv[argc++] = start;
     214                        start = (char *)NULL;
     215                        if (ch == '\n' || ch == '\0')
     216                                goto done;
     217                        continue;
     218                case '\\':
     219                        if (!expand) {
     220                                if (!start)
     221                                        start = t;
     222                                *t++ = '\\';
     223                                ch = *++p;
     224                                break;
     225                        }
     226
     227                        switch (ch = *++p) {
     228                        case '\0':
     229                        case '\n':
     230                                /* hmmm; fix it up as best we can */
     231                                ch = '\\';
     232                                --p;
     233                                break;
     234                        case 'b':
     235                                ch = '\b';
     236                                break;
     237                        case 'f':
     238                                ch = '\f';
     239                                break;
     240                        case 'n':
     241                                ch = '\n';
     242                                break;
     243                        case 'r':
     244                                ch = '\r';
     245                                break;
     246                        case 't':
     247                                ch = '\t';
     248                                break;
     249                        }
     250                        break;
     251                }
     252                if (!start)
     253                        start = t;
     254                *t++ = (char) ch;
     255        }
     256done:   argv[argc] = (char *)NULL;
     257        *store_argc = argc;
     258        return(argv);
    258259}
    259260
     
    270271char *
    271272Str_FindSubstring(string, substring)
    272         register char *string;          /* String to search. */
    273         char *substring;                /* Substring to find in string */
    274 {
    275         register char *a, *b;
    276 
    277         /*
    278         * First scan quickly through the two strings looking for a single-
    279         * character match.  When it's found, then compare the rest of the
    280         * substring.
    281         */
    282 
    283         for (b = substring; *string != 0; string += 1) {
    284                 if (*string != *b)
    285                         continue;
    286                 a = string;
    287                 for (;;) {
    288                         if (*b == 0)
    289                                 return(string);
    290                         if (*a++ != *b++)
    291                                 break;
    292                 }
    293                 b = substring;
    294         }
    295         return((char *) NULL);
     273        register char *string;          /* String to search. */
     274        char *substring;                /* Substring to find in string */
     275{
     276        register char *a, *b;
     277
     278        /*
     279        * First scan quickly through the two strings looking for a single-
     280        * character match.  When it's found, then compare the rest of the
     281        * substring.
     282        */
     283
     284        for (b = substring; *string != 0; string += 1) {
     285                if (*string != *b)
     286                        continue;
     287                a = string;
     288                for (;;) {
     289                        if (*b == 0)
     290                                return(string);
     291                        if (*a++ != *b++)
     292                                break;
     293                }
     294                b = substring;
     295        }
     296        return((char *) NULL);
    296297}
    297298
     
    309310int
    310311Str_Match(string, pattern)
    311         register char *string;          /* String */
    312         register char *pattern;         /* Pattern */
    313 {
    314         char c2;
    315 
    316         for (;;) {
    317                 /*
    318                 * See if we're at the end of both the pattern and the
    319                 * string. If, we succeeded.  If we're at the end of the
    320                 * pattern but not at the end of the string, we failed.
    321                 */
    322                 if (*pattern == 0)
    323                         return(!*string);
    324                 if (*string == 0 && *pattern != '*')
    325                         return(0);
    326                 /*
    327                 * Check for a "*" as the next pattern character.  It matches
    328                 * any substring.  We handle this by calling ourselves
    329                 * recursively for each postfix of string, until either we
    330                 * match or we reach the end of the string.
    331                 */
    332                 if (*pattern == '*') {
    333                         pattern += 1;
    334                         if (*pattern == 0)
    335                                 return(1);
    336                         while (*string != 0) {
    337                                 if (Str_Match(string, pattern))
    338                                         return(1);
    339                                 ++string;
    340                         }
    341                         return(0);
    342                 }
    343                 /*
    344                 * Check for a "?" as the next pattern character.  It matches
    345                 * any single character.
    346                 */
    347                 if (*pattern == '?')
    348                         goto thisCharOK;
    349                 /*
    350                 * Check for a "[" as the next pattern character.  It is
    351                 * followed by a list of characters that are acceptable, or
    352                 * by a range (two characters separated by "-").
    353                 */
    354                 if (*pattern == '[') {
    355                         ++pattern;
    356                         for (;;) {
    357                                 if ((*pattern == ']') || (*pattern == 0))
    358                                         return(0);
    359                                 if (*pattern == *string)
    360                                         break;
    361                                 if (pattern[1] == '-') {
    362                                         c2 = pattern[2];
    363                                         if (c2 == 0)
    364                                                 return(0);
    365                                         if ((*pattern <= *string) &&
    366                                             (c2 >= *string))
    367                                                 break;
    368                                         if ((*pattern >= *string) &&
    369                                             (c2 <= *string))
    370                                                 break;
    371                                         pattern += 2;
    372                                 }
    373                                 ++pattern;
    374                         }
    375                         while ((*pattern != ']') && (*pattern != 0))
    376                                 ++pattern;
    377                         goto thisCharOK;
    378                 }
    379                 /*
    380                 * If the next pattern character is '/', just strip off the
    381                 * '/' so we do exact matching on the character that follows.
    382                 */
    383                 if (*pattern == '\\') {
    384                         ++pattern;
    385                         if (*pattern == 0)
    386                                 return(0);
    387                 }
    388                 /*
    389                 * There's no special character.  Just make sure that the
    390                 * next characters of each string match.
    391                 */
    392                 if (*pattern != *string)
    393                         return(0);
    394 thisCharOK:     ++pattern;
    395                 ++string;
    396         }
     312        register char *string;          /* String */
     313        register char *pattern;         /* Pattern */
     314{
     315        char c2;
     316
     317        for (;;) {
     318                /*
     319                * See if we're at the end of both the pattern and the
     320                * string. If, we succeeded.  If we're at the end of the
     321                * pattern but not at the end of the string, we failed.
     322                */
     323                if (*pattern == 0)
     324                        return(!*string);
     325                if (*string == 0 && *pattern != '*')
     326                        return(0);
     327                /*
     328                * Check for a "*" as the next pattern character.  It matches
     329                * any substring.  We handle this by calling ourselves
     330                * recursively for each postfix of string, until either we
     331                * match or we reach the end of the string.
     332                */
     333                if (*pattern == '*') {
     334                        pattern += 1;
     335                        if (*pattern == 0)
     336                                return(1);
     337                        while (*string != 0) {
     338                                if (Str_Match(string, pattern))
     339                                        return(1);
     340                                ++string;
     341                        }
     342                        return(0);
     343                }
     344                /*
     345                * Check for a "?" as the next pattern character.  It matches
     346                * any single character.
     347                */
     348                if (*pattern == '?')
     349                        goto thisCharOK;
     350                /*
     351                * Check for a "[" as the next pattern character.  It is
     352                * followed by a list of characters that are acceptable, or
     353                * by a range (two characters separated by "-").
     354                */
     355                if (*pattern == '[') {
     356                        ++pattern;
     357                        for (;;) {
     358                                if ((*pattern == ']') || (*pattern == 0))
     359                                        return(0);
     360                                if (*pattern == *string)
     361                                        break;
     362                                if (pattern[1] == '-') {
     363                                        c2 = pattern[2];
     364                                        if (c2 == 0)
     365                                                return(0);
     366                                        if ((*pattern <= *string) &&
     367                                            (c2 >= *string))
     368                                                break;
     369                                        if ((*pattern >= *string) &&
     370                                            (c2 <= *string))
     371                                                break;
     372                                        pattern += 2;
     373                                }
     374                                ++pattern;
     375                        }
     376                        while ((*pattern != ']') && (*pattern != 0))
     377                                ++pattern;
     378                        goto thisCharOK;
     379                }
     380                /*
     381                * If the next pattern character is '/', just strip off the
     382                * '/' so we do exact matching on the character that follows.
     383                */
     384                if (*pattern == '\\') {
     385                        ++pattern;
     386                        if (*pattern == 0)
     387                                return(0);
     388                }
     389                /*
     390                * There's no special character.  Just make sure that the
     391                * next characters of each string match.
     392                */
     393                if (*pattern != *string)
     394                        return(0);
     395thisCharOK:     ++pattern;
     396                ++string;
     397        }
    397398}
    398399
     
    401402 *-----------------------------------------------------------------------
    402403 * Str_SYSVMatch --
    403  *      Check word against pattern for a match (% is wild),
     404 *      Check word against pattern for a match (% is wild),
    404405 *
    405406 * Results:
    406  *      Returns the beginning position of a match or null. The number
    407  *      of characters matched is returned in len.
     407 *      Returns the beginning position of a match or null. The number
     408 *      of characters matched is returned in len.
    408409 *
    409410 * Side Effects:
    410  *      None
     411 *      None
    411412 *
    412413 *-----------------------------------------------------------------------
     
    414415char *
    415416Str_SYSVMatch(word, pattern, len)
    416     char        *word;          /* Word to examine */
    417     char        *pattern;       /* Pattern to examine against */
    418     int         *len;           /* Number of characters to substitute */
     417    char        *word;          /* Word to examine */
     418    char        *pattern;       /* Pattern to examine against */
     419    int         *len;           /* Number of characters to substitute */
    419420{
    420421    char *p = pattern;
     
    423424
    424425    if (*w == '\0') {
    425         /* Zero-length word cannot be matched against */
    426         *len = 0;
    427         return NULL;
     426        /* Zero-length word cannot be matched against */
     427        *len = 0;
     428        return NULL;
    428429    }
    429430
    430431    if (*p == '\0') {
    431         /* Null pattern is the whole string */
    432         *len = strlen(w);
    433         return w;
     432        /* Null pattern is the whole string */
     433        *len = strlen(w);
     434        return w;
    434435    }
    435436
    436437    if ((m = strchr(p, '%')) != NULL) {
    437         /* check that the prefix matches */
    438         for (; p != m && *w && *w == *p; w++, p++)
    439              continue;
    440 
    441         if (p != m)
    442             return NULL;        /* No match */
    443 
    444         if (*++p == '\0') {
    445             /* No more pattern, return the rest of the string */
    446             *len = strlen(w);
    447             return w;
    448         }
     438        /* check that the prefix matches */
     439        for (; p != m && *w && *w == *p; w++, p++)
     440             continue;
     441
     442        if (p != m)
     443            return NULL;        /* No match */
     444
     445        if (*++p == '\0') {
     446            /* No more pattern, return the rest of the string */
     447            *len = strlen(w);
     448            return w;
     449        }
    449450    }
    450451
     
    453454    /* Find a matching tail */
    454455    do
    455         if (strcmp(p, w) == 0) {
    456             *len = w - m;
    457             return m;
    458         }
     456        if (strcmp(p, w) == 0) {
     457            *len = w - m;
     458            return m;
     459        }
    459460    while (*w++ != '\0');
    460461
     
    466467 *-----------------------------------------------------------------------
    467468 * Str_SYSVSubst --
    468  *      Substitute '%' on the pattern with len characters from src.
    469  *      If the pattern does not contain a '%' prepend len characters
    470  *      from src.
     469 *      Substitute '%' on the pattern with len characters from src.
     470 *      If the pattern does not contain a '%' prepend len characters
     471 *      from src.
    471472 *
    472473 * Results:
    473  *      None
     474 *      None
    474475 *
    475476 * Side Effects:
    476  *      Places result on buf
     477 *      Places result on buf
    477478 *
    478479 *-----------------------------------------------------------------------
     
    488489
    489490    if ((m = strchr(pat, '%')) != NULL) {
    490         /* Copy the prefix */
    491         Buf_AddBytes(buf, m - pat, (Byte *) pat);
    492         /* skip the % */
    493         pat = m + 1;
     491        /* Copy the prefix */
     492        Buf_AddBytes(buf, m - pat, (Byte *) pat);
     493        /* skip the % */
     494        pat = m + 1;
    494495    }
    495496
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette