[BACK]Return to compile.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libterminfo

Annotation of src/lib/libterminfo/compile.c, Revision 1.4

1.4     ! roy         1: /* $NetBSD: compile.c,v 1.3 2010/03/01 01:59:48 dholland Exp $ */
1.1       roy         2:
                      3: /*
                      4:  * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
                      5:  *
                      6:  * This code is derived from software contributed to The NetBSD Foundation
                      7:  * by Roy Marples.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     23:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     27:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     28:  */
                     29:
                     30: #if HAVE_NBTOOL_CONFIG_H
                     31: #include "nbtool_config.h"
                     32: #endif
                     33:
                     34: #include <sys/cdefs.h>
1.4     ! roy        35: __RCSID("$NetBSD: compile.c,v 1.3 2010/03/01 01:59:48 dholland Exp $");
1.3       dholland   36:
                     37: #if !HAVE_NBTOOL_CONFIG_H || HAVE_SYS_ENDIAN_H
                     38: #include <sys/endian.h>
                     39: #endif
1.1       roy        40:
                     41: #include <assert.h>
                     42: #include <ctype.h>
                     43: #include <err.h>
                     44: #include <errno.h>
                     45: #include <limits.h>
                     46: #include <stdarg.h>
                     47: #include <stdlib.h>
                     48: #include <stdint.h>
                     49: #include <stdio.h>
                     50: #include <string.h>
                     51: #include <term_private.h>
                     52: #include <term.h>
                     53:
                     54: static void __attribute__((__format__(__printf__, 2, 3)))
                     55: dowarn(int flags, const char *fmt, ...)
                     56: {
                     57:        va_list va;
                     58:
                     59:        errno = EINVAL;
                     60:        if (flags & TIC_WARNING) {
                     61:                va_start(va, fmt);
                     62:                vwarnx(fmt, va);
                     63:                va_end(va);
                     64:        }
                     65: }
                     66:
                     67: char *
                     68: _ti_grow_tbuf(TBUF *tbuf, size_t len)
                     69: {
                     70:        char *buf;
                     71:        size_t l;
                     72:
                     73:        _DIAGASSERT(tbuf != NULL);
                     74:
                     75:        l = tbuf->bufpos + len;
                     76:        if (l > tbuf->buflen) {
                     77:                if (tbuf->bufpos == 0)
                     78:                        buf = malloc(l);
                     79:                else
                     80:                        buf = realloc(tbuf->buf, l);
                     81:                if (buf == NULL)
                     82:                        return NULL;
                     83:                tbuf->buf = buf;
                     84:                tbuf->buflen = l;
                     85:        }
                     86:        return tbuf->buf;
                     87: }
                     88:
                     89: char *
                     90: _ti_find_cap(TBUF *tbuf, char type, short ind)
                     91: {
                     92:        size_t n;
                     93:        short num;
                     94:        char *cap;
                     95:
                     96:        _DIAGASSERT(tbuf != NULL);
                     97:
                     98:        cap = tbuf->buf;
                     99:        for (n = tbuf->entries; n > 0; n--) {
                    100:                num = le16dec(cap);
                    101:                cap += sizeof(uint16_t);
                    102:                if (num == ind)
                    103:                        return cap;
                    104:                switch (type) {
                    105:                case 'f':
                    106:                        cap++;
                    107:                        break;
                    108:                case 'n':
                    109:                        cap += sizeof(uint16_t);
                    110:                        break;
                    111:                case 's':
                    112:                        num = le16dec(cap);
                    113:                        cap += sizeof(uint16_t);
                    114:                        cap += num;
                    115:                        break;
                    116:                }
                    117:        }
                    118:
                    119:        errno = ESRCH;
                    120:        return NULL;
                    121: }
                    122:
                    123: char *
                    124: _ti_find_extra(TBUF *tbuf, const char *code)
                    125: {
                    126:        size_t n;
                    127:        short num;
                    128:        char *cap;
                    129:
                    130:        _DIAGASSERT(tbuf != NULL);
                    131:        _DIAGASSERT(code != NULL);
                    132:
                    133:        cap = tbuf->buf;
                    134:        for (n = tbuf->entries; n > 0; n--) {
                    135:                num = le16dec(cap);
                    136:                cap += sizeof(uint16_t);
                    137:                if (strcmp(cap, code) == 0)
                    138:                        return cap + num;
                    139:                cap += num;
                    140:                switch (*cap++) {
                    141:                case 'f':
                    142:                        cap++;
                    143:                        break;
                    144:                case 'n':
                    145:                        cap += sizeof(uint16_t);
                    146:                        break;
                    147:                case 's':
                    148:                        num = le16dec(cap);
                    149:                        cap += sizeof(uint16_t);
                    150:                        cap += num;
                    151:                        break;
                    152:                }
                    153:        }
                    154:
                    155:        errno = ESRCH;
                    156:        return NULL;
                    157: }
                    158:
                    159: size_t
                    160: _ti_store_extra(TIC *tic, int wrn, char *id, char type, char flag, short num,
                    161:     char *str, size_t strl, int flags)
                    162: {
                    163:        size_t l;
                    164:
                    165:        _DIAGASSERT(tic != NULL);
                    166:
                    167:        if (strcmp(id, "use") != 0) {
                    168:                if (_ti_find_extra(&tic->extras, id) != NULL)
                    169:                        return 0;
                    170:                if (!(flags & TIC_EXTRA)) {
                    171:                        if (wrn != 0)
                    172:                                dowarn(flags, "%s: %s: unknown capability",
                    173:                                    tic->name, id);
                    174:                        return 0;
                    175:                }
                    176:        }
                    177:
                    178:        l = strlen(id) + 1;
                    179:        if (l > UINT16_T_MAX) {
                    180:                dowarn(flags, "%s: %s: cap name is too long", tic->name, id);
                    181:                return 0;
                    182:        }
                    183:
                    184:        if (!_ti_grow_tbuf(&tic->extras,
                    185:                l + strl + (sizeof(uint16_t) * 2) + 1))
                    186:                return 0;
                    187:        le16enc(tic->extras.buf + tic->extras.bufpos, l);
                    188:        tic->extras.bufpos += sizeof(uint16_t);
                    189:        memcpy(tic->extras.buf + tic->extras.bufpos, id, l);
                    190:        tic->extras.bufpos += l;
                    191:        tic->extras.buf[tic->extras.bufpos++] = type;
                    192:        switch (type) {
                    193:        case 'f':
                    194:                tic->extras.buf[tic->extras.bufpos++] = flag;
                    195:                break;
                    196:        case 'n':
                    197:                le16enc(tic->extras.buf + tic->extras.bufpos, num);
                    198:                tic->extras.bufpos += sizeof(uint16_t);
                    199:                break;
                    200:        case 's':
                    201:                le16enc(tic->extras.buf + tic->extras.bufpos, strl);
                    202:                tic->extras.bufpos += sizeof(uint16_t);
                    203:                memcpy(tic->extras.buf + tic->extras.bufpos, str, strl);
                    204:                tic->extras.bufpos += strl;
                    205:                break;
                    206:        }
                    207:        tic->extras.entries++;
                    208:        return 1;
                    209: }
                    210:
                    211: ssize_t
                    212: _ti_flatten(uint8_t **buf, const TIC *tic)
                    213: {
                    214:        size_t buflen, len, alen, dlen;
                    215:        uint8_t *cap;
                    216:
                    217:        _DIAGASSERT(buf != NULL);
                    218:        _DIAGASSERT(tic != NULL);
                    219:
                    220:        len = strlen(tic->name) + 1;
                    221:        if (tic->alias == NULL)
                    222:                alen = 0;
                    223:        else
                    224:                alen = strlen(tic->alias) + 1;
                    225:        if (tic->desc == NULL)
                    226:                dlen = 0;
                    227:        else
                    228:                dlen = strlen(tic->desc) + 1;
                    229:        buflen = sizeof(char) +
                    230:            sizeof(uint16_t) + len +
                    231:            sizeof(uint16_t) + alen +
                    232:            sizeof(uint16_t) + dlen +
                    233:            (sizeof(uint16_t) * 2) + tic->flags.bufpos +
                    234:            (sizeof(uint16_t) * 2) + tic->nums.bufpos +
                    235:            (sizeof(uint16_t) * 2) + tic->strs.bufpos +
                    236:            (sizeof(uint16_t) * 2) + tic->extras.bufpos;
                    237:        *buf = malloc(buflen);
                    238:        if (*buf == NULL)
                    239:                return -1;
                    240:
                    241:        cap = *buf;
1.2       roy       242:        if (alen == 0 && dlen == 0 && tic->flags.bufpos == 0 &&
                    243:            tic->nums.bufpos == 0 && tic->strs.bufpos == 0 &&
                    244:            tic->extras.bufpos == 0)
                    245:                *cap++ = 0; /* alias */
                    246:        else
                    247:                *cap++ = 2; /* version */
1.1       roy       248:        le16enc(cap, len);
                    249:        cap += sizeof(uint16_t);
                    250:        memcpy(cap, tic->name, len);
                    251:        cap += len;
                    252:
                    253:        le16enc(cap, alen);
                    254:        cap += sizeof(uint16_t);
                    255:        if (tic->alias != NULL) {
                    256:                memcpy(cap, tic->alias, alen);
                    257:                cap += alen;
                    258:        }
                    259:        le16enc(cap, dlen);
                    260:        cap += sizeof(uint16_t);
                    261:        if (tic->desc != NULL) {
                    262:                memcpy(cap, tic->desc, dlen);
                    263:                cap += dlen;
                    264:        }
                    265:
                    266:        if (tic->flags.entries == 0) {
                    267:                le16enc(cap, 0);
                    268:                cap += sizeof(uint16_t);
                    269:        } else {
                    270:                le16enc(cap, (tic->flags.bufpos + sizeof(uint16_t)));
                    271:                cap += sizeof(uint16_t);
                    272:                le16enc(cap, tic->flags.entries);
                    273:                cap += sizeof(uint16_t);
                    274:                memcpy(cap, tic->flags.buf, tic->flags.bufpos);
                    275:                cap += tic->flags.bufpos;
                    276:        }
                    277:
                    278:        if (tic->nums.entries == 0) {
                    279:                le16enc(cap, 0);
                    280:                cap += sizeof(uint16_t);
                    281:        } else {
                    282:                le16enc(cap, (tic->nums.bufpos + sizeof(uint16_t)));
                    283:                cap += sizeof(uint16_t);
                    284:                le16enc(cap, tic->nums.entries);
                    285:                cap += sizeof(uint16_t);
                    286:                memcpy(cap, tic->nums.buf, tic->nums.bufpos);
                    287:                cap += tic->nums.bufpos;
                    288:        }
                    289:
                    290:        if (tic->strs.entries == 0) {
                    291:                le16enc(cap, 0);
                    292:                cap += sizeof(uint16_t);
                    293:        } else {
                    294:                le16enc(cap, (tic->strs.bufpos + sizeof(uint16_t)));
                    295:                cap += sizeof(uint16_t);
                    296:                le16enc(cap, tic->strs.entries);
                    297:                cap += sizeof(uint16_t);
                    298:                memcpy(cap, tic->strs.buf, tic->strs.bufpos);
                    299:                cap += tic->strs.bufpos;
                    300:        }
                    301:
                    302:        if (tic->extras.entries == 0) {
                    303:                le16enc(cap, 0);
                    304:                cap += sizeof(uint16_t);
                    305:        } else {
                    306:                le16enc(cap, (tic->extras.bufpos + sizeof(uint16_t)));
                    307:                cap += sizeof(uint16_t);
                    308:                le16enc(cap, tic->extras.entries);
                    309:                cap += sizeof(uint16_t);
                    310:                memcpy(cap, tic->extras.buf, tic->extras.bufpos);
                    311:                cap += tic->extras.bufpos;
                    312:        }
                    313:
                    314:        return cap - *buf;
                    315: }
                    316:
                    317: static int
                    318: encode_string(const char *term, const char *cap, TBUF *tbuf, const char *str,
                    319:     int flags)
                    320: {
                    321:        int slash, i, num;
                    322:        char ch, *p, *s, last;
                    323:
                    324:        if (_ti_grow_tbuf(tbuf, strlen(str) + 1) == NULL)
                    325:                return -1;
                    326:        p = s = tbuf->buf + tbuf->bufpos;
                    327:        slash = 0;
                    328:        last = '\0';
                    329:        /* Convert escape codes */
                    330:        while ((ch = *str++) != '\0') {
                    331:                if (slash == 0 && ch == '\\') {
                    332:                        slash = 1;
                    333:                        continue;
                    334:                }
                    335:                if (slash == 0) {
                    336:                        if (last != '%' && ch == '^') {
                    337:                                ch = *str++;
                    338:                                if (((unsigned char)ch) >= 128)
                    339:                                        dowarn(flags,
                    340:                                            "%s: %s: illegal ^ character",
                    341:                                            term, cap);
                    342:                                if (ch == '\0')
                    343:                                        break;
                    344:                                if (ch == '?')
                    345:                                        ch = '\177';
                    346:                                else if ((ch &= 037) == 0)
                    347:                                        ch = 128;
                    348:                        }
                    349:                        *p++ = ch;
                    350:                        last = ch;
                    351:                        continue;
                    352:                }
                    353:                slash = 0;
                    354:                if (ch >= '0' && ch <= '7') {
                    355:                        num = ch - '0';
                    356:                        for (i = 0; i < 2; i++) {
                    357:                                if (*str < '0' || *str > '7') {
                    358:                                        if (isdigit((unsigned char)*str))
                    359:                                                dowarn(flags,
                    360:                                                    "%s: %s: non octal"
                    361:                                                    " digit", term, cap);
                    362:                                        else
                    363:                                                break;
                    364:                                }
                    365:                                num = num * 8 + *str++ - '0';
                    366:                        }
                    367:                        if (num == 0)
                    368:                                num = 0200;
                    369:                        *p++ = (char)num;
                    370:                        continue;
                    371:                }
                    372:                switch (ch) {
                    373:                case 'a':
                    374:                        *p++ = '\a';
                    375:                        break;
                    376:                case 'b':
                    377:                        *p++ = '\b';
                    378:                        break;
                    379:                case 'e': /* FALLTHROUGH */
                    380:                case 'E':
                    381:                        *p++ = '\033';
                    382:                        break;
                    383:                case 'f':
                    384:                        *p++ = '\014';
                    385:                        break;
                    386:                case 'l': /* FALLTHROUGH */
                    387:                case 'n':
                    388:                        *p++ = '\n';
                    389:                        break;
                    390:                case 'r':
                    391:                        *p++ = '\r';
                    392:                        break;
                    393:                case 's':
                    394:                        *p++ = ' ';
                    395:                        break;
                    396:                case 't':
                    397:                        *p++ = '\t';
                    398:                        break;
                    399:                default:
                    400:
                    401:                        /* We should warn here */
                    402:                case '^':
                    403:                case ',':
                    404:                case ':':
                    405:                case '|':
                    406:                        *p++ = ch;
                    407:                        break;
                    408:                }
                    409:                last = ch;
                    410:        }
                    411:        *p++ = '\0';
                    412:        tbuf->bufpos += p - s;
                    413:        return 0;
                    414: }
                    415:
1.4     ! roy       416: char *
        !           417: _ti_get_token(char **cap, char sep)
1.1       roy       418: {
1.4     ! roy       419:        char esc, *token;
1.1       roy       420:
                    421:        while (isspace((unsigned char)**cap))
                    422:                (*cap)++;
                    423:        if (**cap == '\0')
                    424:                return NULL;
                    425:
                    426:        /* We can't use stresep(3) as ^ we need two escape chars */
1.4     ! roy       427:        esc = '\0';
1.1       roy       428:        for (token = *cap;
1.4     ! roy       429:             **cap != '\0' && (esc != '\0' || **cap != sep);
1.1       roy       430:             (*cap)++)
                    431:        {
1.4     ! roy       432:                if (esc == '\0') {
1.1       roy       433:                        if (**cap == '\\' || **cap == '^')
1.4     ! roy       434:                                esc = **cap;
        !           435:                } else {
        !           436:                        /* termcap /E/ is valid */
        !           437:                        if (sep == ':' && esc == '\\' && **cap == 'E')
        !           438:                                esc = 'x';
        !           439:                        else
        !           440:                                esc = '\0';
        !           441:                }
1.1       roy       442:        }
                    443:
                    444:        if (**cap != '\0')
                    445:                *(*cap)++ = '\0';
                    446:
                    447:        return token;
                    448: }
                    449:
                    450: TIC *
                    451: _ti_compile(char *cap, int flags)
                    452: {
                    453:        char *token, *p, *e, *name, *desc, *alias;
                    454:        signed char flag;
                    455:        long num;
                    456:        ssize_t ind;
                    457:        size_t len;
                    458:        TBUF buf;
                    459:        TIC *tic;
                    460:
                    461:        _DIAGASSERT(cap != NULL);
                    462:
1.4     ! roy       463:        name = _ti_get_token(&cap, ',');
1.1       roy       464:        if (name == NULL) {
                    465:                dowarn(flags, "no seperator found: %s", cap);
                    466:                return NULL;
                    467:        }
                    468:        desc = strrchr(name, '|');
                    469:        if (desc != NULL)
                    470:                *desc++ = '\0';
                    471:        alias = strchr(name, '|');
                    472:        if (alias != NULL)
                    473:                *alias++ = '\0';
                    474:
                    475:        tic = calloc(sizeof(*tic), 1);
                    476:        if (tic == NULL)
                    477:                return NULL;
                    478:
                    479:        buf.buf = NULL;
                    480:        buf.buflen = 0;
                    481:
                    482:        tic->name = strdup(name);
                    483:        if (tic->name == NULL)
                    484:                goto error;
                    485:        if (alias != NULL && flags & TIC_ALIAS) {
                    486:                tic->alias = strdup(alias);
                    487:                if (tic->alias == NULL)
                    488:                        goto error;
                    489:        }
                    490:        if (desc != NULL && flags & TIC_DESCRIPTION) {
                    491:                tic->desc = strdup(desc);
                    492:                if (tic->desc == NULL)
                    493:                        goto error;
                    494:        }
                    495:
1.4     ! roy       496:        for (token = _ti_get_token(&cap, ',');
1.1       roy       497:             token != NULL && *token != '\0';
1.4     ! roy       498:             token = _ti_get_token(&cap, ','))
1.1       roy       499:        {
                    500:                /* Skip commented caps */
                    501:                if (!(flags & TIC_COMMENT) && token[0] == '.')
                    502:                        continue;
                    503:
                    504:                /* Obsolete entries */
                    505:                if (token[0] == 'O' && token[1] == 'T') {
                    506:                        if (!(flags & TIC_EXTRA))
                    507:                                continue;
                    508:                        token += 2;
                    509:                }
                    510:
                    511:                /* str cap */
                    512:                p = strchr(token, '=');
                    513:                if (p != NULL) {
                    514:                        *p++ = '\0';
                    515:                        /* Don't use the string if we already have it */
                    516:                        ind = _ti_strindex(token);
                    517:                        if (ind != -1 &&
                    518:                            _ti_find_cap(&tic->strs, 's', ind) != NULL)
                    519:                                continue;
                    520:
                    521:                        /* Encode the string to our scratch buffer */
                    522:                        buf.bufpos = 0;
                    523:                        if (encode_string(tic->name, token,
                    524:                                &buf, p, flags) == -1)
                    525:                                goto error;
                    526:                        if (buf.bufpos > UINT16_T_MAX) {
                    527:                                dowarn(flags, "%s: %s: string is too long",
                    528:                                    tic->name, token);
                    529:                                continue;
                    530:                        }
                    531:                        if (!VALID_STRING(buf.buf)) {
                    532:                                dowarn(flags, "%s: %s: invalid string",
                    533:                                    tic->name, token);
                    534:                                continue;
                    535:                        }
                    536:
                    537:                        if (ind == -1)
                    538:                                _ti_store_extra(tic, 1, token, 's', -1, -2,
                    539:                                    buf.buf, buf.bufpos, flags);
                    540:                        else {
                    541:                                if (!_ti_grow_tbuf(&tic->strs,
                    542:                                        (sizeof(uint16_t) * 2) + buf.bufpos))
                    543:                                        goto error;
                    544:                                le16enc(tic->strs.buf + tic->strs.bufpos, ind);
                    545:                                tic->strs.bufpos += sizeof(uint16_t);
                    546:                                le16enc(tic->strs.buf + tic->strs.bufpos,
                    547:                                    buf.bufpos);
                    548:                                tic->strs.bufpos += sizeof(uint16_t);
                    549:                                memcpy(tic->strs.buf + tic->strs.bufpos,
                    550:                                    buf.buf, buf.bufpos);
                    551:                                tic->strs.bufpos += buf.bufpos;
                    552:                                tic->strs.entries++;
                    553:                        }
                    554:                        continue;
                    555:                }
                    556:
                    557:                /* num cap */
                    558:                p = strchr(token, '#');
                    559:                if (p != NULL) {
                    560:                        *p++ = '\0';
                    561:                        /* Don't use the number if we already have it */
                    562:                        ind = _ti_numindex(token);
                    563:                        if (ind != -1 &&
                    564:                            _ti_find_cap(&tic->nums, 'n', ind) != NULL)
                    565:                                continue;
                    566:
                    567:                        num = strtol(p, &e, 0);
                    568:                        if (*e != '\0') {
                    569:                                dowarn(flags, "%s: %s: not a number",
                    570:                                    tic->name, token);
                    571:                                continue;
                    572:                        }
                    573:                        if (!VALID_NUMERIC(num)) {
                    574:                                dowarn(flags, "%s: %s: number out of range",
                    575:                                    tic->name, token);
                    576:                                continue;
                    577:                        }
                    578:                        if (ind == -1)
                    579:                                _ti_store_extra(tic, 1, token, 'n', -1,
                    580:                                    num, NULL, 0, flags);
                    581:                        else {
                    582:                                if (_ti_grow_tbuf(&tic->nums,
                    583:                                        sizeof(uint16_t) * 2) == NULL)
                    584:                                        goto error;
                    585:                                le16enc(tic->nums.buf + tic->nums.bufpos, ind);
                    586:                                tic->nums.bufpos += sizeof(uint16_t);
                    587:                                le16enc(tic->nums.buf + tic->nums.bufpos, num);
                    588:                                tic->nums.bufpos += sizeof(uint16_t);
                    589:                                tic->nums.entries++;
                    590:                        }
                    591:                        continue;
                    592:                }
                    593:
                    594:                flag = 1;
                    595:                len = strlen(token) - 1;
                    596:                if (token[len] == '@') {
                    597:                        flag = CANCELLED_BOOLEAN;
                    598:                        token[len] = '\0';
                    599:                }
                    600:                ind = _ti_flagindex(token);
                    601:                if (ind == -1 && flag == CANCELLED_BOOLEAN) {
                    602:                        if ((ind = _ti_numindex(token)) != -1) {
                    603:                                if (_ti_find_cap(&tic->nums, 'n', ind) != NULL)
                    604:                                        continue;
                    605:                                if (_ti_grow_tbuf(&tic->nums,
                    606:                                        sizeof(uint16_t) * 2) == NULL)
                    607:                                        goto error;
                    608:                                le16enc(tic->nums.buf + tic->nums.bufpos, ind);
                    609:                                tic->nums.bufpos += sizeof(uint16_t);
                    610:                                le16enc(tic->nums.buf + tic->nums.bufpos,
                    611:                                        CANCELLED_NUMERIC);
                    612:                                tic->nums.bufpos += sizeof(uint16_t);
                    613:                                tic->nums.entries++;
                    614:                                continue;
                    615:                        } else if ((ind = _ti_strindex(token)) != -1) {
                    616:                                if (_ti_find_cap(&tic->strs, 's', ind) != NULL)
                    617:                                        continue;
                    618:                                if (_ti_grow_tbuf(&tic->strs,
                    619:                                        (sizeof(uint16_t) * 2) + 1) == NULL)
                    620:                                        goto error;
                    621:                                le16enc(tic->strs.buf + tic->strs.bufpos, ind);
                    622:                                tic->strs.bufpos += sizeof(uint16_t);
                    623:                                le16enc(tic->strs.buf + tic->strs.bufpos, 0);
                    624:                                tic->strs.bufpos += sizeof(uint16_t);
                    625:                                tic->strs.entries++;
                    626:                                continue;
                    627:                        }
                    628:                }
                    629:                if (ind == -1)
                    630:                        _ti_store_extra(tic, 1, token, 'f', flag, 0, NULL, 0,
                    631:                            flags);
                    632:                else if (_ti_find_cap(&tic->flags, 'f', ind) == NULL) {
                    633:                        if (_ti_grow_tbuf(&tic->flags, sizeof(uint16_t) + 1)
                    634:                            == NULL)
                    635:                                goto error;
                    636:                        le16enc(tic->flags.buf + tic->flags.bufpos, ind);
                    637:                        tic->flags.bufpos += sizeof(uint16_t);
                    638:                        tic->flags.buf[tic->flags.bufpos++] = flag;
                    639:                        tic->flags.entries++;
                    640:                }
                    641:        }
                    642:
                    643:        free(buf.buf);
                    644:        return tic;
                    645:
                    646: error:
                    647:        free(buf.buf);
                    648:        _ti_freetic(tic);
                    649:        return NULL;
                    650: }
                    651:
                    652: void
                    653: _ti_freetic(TIC *tic)
                    654: {
                    655:
                    656:        if (tic != NULL) {
                    657:                free(tic->name);
                    658:                free(tic->alias);
                    659:                free(tic->desc);
                    660:                free(tic->flags.buf);
                    661:                free(tic->nums.buf);
                    662:                free(tic->strs.buf);
                    663:                free(tic);
                    664:        }
                    665: }

CVSweb <webmaster@jp.NetBSD.org>