[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.6.2.1

1.6.2.1 ! riz         1: /* $NetBSD$ */
1.1       roy         2:
                      3: /*
1.5       roy         4:  * Copyright (c) 2009, 2010, 2011 The NetBSD Foundation, Inc.
1.1       roy         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.6.2.1 ! riz        35: __RCSID("$NetBSD$");
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:
1.6       joerg      54: static void __printflike(2, 3)
1.1       roy        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) {
1.6.2.1 ! riz        77:                if (tbuf->buflen == 0)
1.1       roy        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.6.2.1 ! riz       242:        *cap++ = 1;
1.1       roy       243:        le16enc(cap, len);
                    244:        cap += sizeof(uint16_t);
                    245:        memcpy(cap, tic->name, len);
                    246:        cap += len;
                    247:
                    248:        le16enc(cap, alen);
                    249:        cap += sizeof(uint16_t);
                    250:        if (tic->alias != NULL) {
                    251:                memcpy(cap, tic->alias, alen);
                    252:                cap += alen;
                    253:        }
                    254:        le16enc(cap, dlen);
                    255:        cap += sizeof(uint16_t);
                    256:        if (tic->desc != NULL) {
                    257:                memcpy(cap, tic->desc, dlen);
                    258:                cap += dlen;
                    259:        }
                    260:
                    261:        if (tic->flags.entries == 0) {
                    262:                le16enc(cap, 0);
                    263:                cap += sizeof(uint16_t);
                    264:        } else {
                    265:                le16enc(cap, (tic->flags.bufpos + sizeof(uint16_t)));
                    266:                cap += sizeof(uint16_t);
                    267:                le16enc(cap, tic->flags.entries);
                    268:                cap += sizeof(uint16_t);
                    269:                memcpy(cap, tic->flags.buf, tic->flags.bufpos);
                    270:                cap += tic->flags.bufpos;
                    271:        }
                    272:
                    273:        if (tic->nums.entries == 0) {
                    274:                le16enc(cap, 0);
                    275:                cap += sizeof(uint16_t);
                    276:        } else {
                    277:                le16enc(cap, (tic->nums.bufpos + sizeof(uint16_t)));
                    278:                cap += sizeof(uint16_t);
                    279:                le16enc(cap, tic->nums.entries);
                    280:                cap += sizeof(uint16_t);
                    281:                memcpy(cap, tic->nums.buf, tic->nums.bufpos);
                    282:                cap += tic->nums.bufpos;
                    283:        }
                    284:
                    285:        if (tic->strs.entries == 0) {
                    286:                le16enc(cap, 0);
                    287:                cap += sizeof(uint16_t);
                    288:        } else {
                    289:                le16enc(cap, (tic->strs.bufpos + sizeof(uint16_t)));
                    290:                cap += sizeof(uint16_t);
                    291:                le16enc(cap, tic->strs.entries);
                    292:                cap += sizeof(uint16_t);
                    293:                memcpy(cap, tic->strs.buf, tic->strs.bufpos);
                    294:                cap += tic->strs.bufpos;
                    295:        }
                    296:
                    297:        if (tic->extras.entries == 0) {
                    298:                le16enc(cap, 0);
                    299:                cap += sizeof(uint16_t);
                    300:        } else {
                    301:                le16enc(cap, (tic->extras.bufpos + sizeof(uint16_t)));
                    302:                cap += sizeof(uint16_t);
                    303:                le16enc(cap, tic->extras.entries);
                    304:                cap += sizeof(uint16_t);
                    305:                memcpy(cap, tic->extras.buf, tic->extras.bufpos);
                    306:                cap += tic->extras.bufpos;
                    307:        }
                    308:
                    309:        return cap - *buf;
                    310: }
                    311:
                    312: static int
                    313: encode_string(const char *term, const char *cap, TBUF *tbuf, const char *str,
                    314:     int flags)
                    315: {
                    316:        int slash, i, num;
                    317:        char ch, *p, *s, last;
                    318:
                    319:        if (_ti_grow_tbuf(tbuf, strlen(str) + 1) == NULL)
                    320:                return -1;
                    321:        p = s = tbuf->buf + tbuf->bufpos;
                    322:        slash = 0;
                    323:        last = '\0';
                    324:        /* Convert escape codes */
                    325:        while ((ch = *str++) != '\0') {
                    326:                if (slash == 0 && ch == '\\') {
                    327:                        slash = 1;
                    328:                        continue;
                    329:                }
                    330:                if (slash == 0) {
                    331:                        if (last != '%' && ch == '^') {
                    332:                                ch = *str++;
                    333:                                if (((unsigned char)ch) >= 128)
                    334:                                        dowarn(flags,
                    335:                                            "%s: %s: illegal ^ character",
                    336:                                            term, cap);
                    337:                                if (ch == '\0')
                    338:                                        break;
                    339:                                if (ch == '?')
                    340:                                        ch = '\177';
                    341:                                else if ((ch &= 037) == 0)
1.5       roy       342:                                        ch = (char)128;
1.1       roy       343:                        }
                    344:                        *p++ = ch;
                    345:                        last = ch;
                    346:                        continue;
                    347:                }
                    348:                slash = 0;
                    349:                if (ch >= '0' && ch <= '7') {
                    350:                        num = ch - '0';
                    351:                        for (i = 0; i < 2; i++) {
                    352:                                if (*str < '0' || *str > '7') {
                    353:                                        if (isdigit((unsigned char)*str))
                    354:                                                dowarn(flags,
                    355:                                                    "%s: %s: non octal"
                    356:                                                    " digit", term, cap);
                    357:                                        else
                    358:                                                break;
                    359:                                }
                    360:                                num = num * 8 + *str++ - '0';
                    361:                        }
                    362:                        if (num == 0)
                    363:                                num = 0200;
                    364:                        *p++ = (char)num;
                    365:                        continue;
                    366:                }
                    367:                switch (ch) {
                    368:                case 'a':
                    369:                        *p++ = '\a';
                    370:                        break;
                    371:                case 'b':
                    372:                        *p++ = '\b';
                    373:                        break;
                    374:                case 'e': /* FALLTHROUGH */
                    375:                case 'E':
                    376:                        *p++ = '\033';
                    377:                        break;
                    378:                case 'f':
                    379:                        *p++ = '\014';
                    380:                        break;
                    381:                case 'l': /* FALLTHROUGH */
                    382:                case 'n':
                    383:                        *p++ = '\n';
                    384:                        break;
                    385:                case 'r':
                    386:                        *p++ = '\r';
                    387:                        break;
                    388:                case 's':
                    389:                        *p++ = ' ';
                    390:                        break;
                    391:                case 't':
                    392:                        *p++ = '\t';
                    393:                        break;
                    394:                default:
                    395:
                    396:                        /* We should warn here */
                    397:                case '^':
                    398:                case ',':
                    399:                case ':':
                    400:                case '|':
                    401:                        *p++ = ch;
                    402:                        break;
                    403:                }
                    404:                last = ch;
                    405:        }
                    406:        *p++ = '\0';
                    407:        tbuf->bufpos += p - s;
                    408:        return 0;
                    409: }
                    410:
1.4       roy       411: char *
                    412: _ti_get_token(char **cap, char sep)
1.1       roy       413: {
1.4       roy       414:        char esc, *token;
1.1       roy       415:
                    416:        while (isspace((unsigned char)**cap))
                    417:                (*cap)++;
                    418:        if (**cap == '\0')
                    419:                return NULL;
                    420:
                    421:        /* We can't use stresep(3) as ^ we need two escape chars */
1.4       roy       422:        esc = '\0';
1.1       roy       423:        for (token = *cap;
1.4       roy       424:             **cap != '\0' && (esc != '\0' || **cap != sep);
1.1       roy       425:             (*cap)++)
                    426:        {
1.4       roy       427:                if (esc == '\0') {
1.1       roy       428:                        if (**cap == '\\' || **cap == '^')
1.4       roy       429:                                esc = **cap;
                    430:                } else {
                    431:                        /* termcap /E/ is valid */
                    432:                        if (sep == ':' && esc == '\\' && **cap == 'E')
                    433:                                esc = 'x';
                    434:                        else
                    435:                                esc = '\0';
                    436:                }
1.1       roy       437:        }
                    438:
                    439:        if (**cap != '\0')
                    440:                *(*cap)++ = '\0';
                    441:
                    442:        return token;
                    443: }
                    444:
                    445: TIC *
                    446: _ti_compile(char *cap, int flags)
                    447: {
                    448:        char *token, *p, *e, *name, *desc, *alias;
                    449:        signed char flag;
1.5       roy       450:        long cnum;
                    451:        short num;
1.1       roy       452:        ssize_t ind;
                    453:        size_t len;
                    454:        TBUF buf;
                    455:        TIC *tic;
                    456:
                    457:        _DIAGASSERT(cap != NULL);
                    458:
1.4       roy       459:        name = _ti_get_token(&cap, ',');
1.1       roy       460:        if (name == NULL) {
                    461:                dowarn(flags, "no seperator found: %s", cap);
                    462:                return NULL;
                    463:        }
                    464:        desc = strrchr(name, '|');
                    465:        if (desc != NULL)
                    466:                *desc++ = '\0';
                    467:        alias = strchr(name, '|');
                    468:        if (alias != NULL)
                    469:                *alias++ = '\0';
                    470:
                    471:        tic = calloc(sizeof(*tic), 1);
                    472:        if (tic == NULL)
                    473:                return NULL;
                    474:
                    475:        buf.buf = NULL;
                    476:        buf.buflen = 0;
                    477:
                    478:        tic->name = strdup(name);
                    479:        if (tic->name == NULL)
                    480:                goto error;
                    481:        if (alias != NULL && flags & TIC_ALIAS) {
                    482:                tic->alias = strdup(alias);
                    483:                if (tic->alias == NULL)
                    484:                        goto error;
                    485:        }
                    486:        if (desc != NULL && flags & TIC_DESCRIPTION) {
                    487:                tic->desc = strdup(desc);
                    488:                if (tic->desc == NULL)
                    489:                        goto error;
                    490:        }
                    491:
1.4       roy       492:        for (token = _ti_get_token(&cap, ',');
1.1       roy       493:             token != NULL && *token != '\0';
1.4       roy       494:             token = _ti_get_token(&cap, ','))
1.1       roy       495:        {
                    496:                /* Skip commented caps */
                    497:                if (!(flags & TIC_COMMENT) && token[0] == '.')
                    498:                        continue;
                    499:
                    500:                /* Obsolete entries */
                    501:                if (token[0] == 'O' && token[1] == 'T') {
                    502:                        if (!(flags & TIC_EXTRA))
                    503:                                continue;
                    504:                        token += 2;
                    505:                }
                    506:
                    507:                /* str cap */
                    508:                p = strchr(token, '=');
                    509:                if (p != NULL) {
                    510:                        *p++ = '\0';
                    511:                        /* Don't use the string if we already have it */
                    512:                        ind = _ti_strindex(token);
                    513:                        if (ind != -1 &&
                    514:                            _ti_find_cap(&tic->strs, 's', ind) != NULL)
                    515:                                continue;
                    516:
                    517:                        /* Encode the string to our scratch buffer */
                    518:                        buf.bufpos = 0;
                    519:                        if (encode_string(tic->name, token,
                    520:                                &buf, p, flags) == -1)
                    521:                                goto error;
                    522:                        if (buf.bufpos > UINT16_T_MAX) {
                    523:                                dowarn(flags, "%s: %s: string is too long",
                    524:                                    tic->name, token);
                    525:                                continue;
                    526:                        }
                    527:                        if (!VALID_STRING(buf.buf)) {
                    528:                                dowarn(flags, "%s: %s: invalid string",
                    529:                                    tic->name, token);
                    530:                                continue;
                    531:                        }
                    532:
                    533:                        if (ind == -1)
                    534:                                _ti_store_extra(tic, 1, token, 's', -1, -2,
                    535:                                    buf.buf, buf.bufpos, flags);
                    536:                        else {
                    537:                                if (!_ti_grow_tbuf(&tic->strs,
                    538:                                        (sizeof(uint16_t) * 2) + buf.bufpos))
                    539:                                        goto error;
                    540:                                le16enc(tic->strs.buf + tic->strs.bufpos, ind);
                    541:                                tic->strs.bufpos += sizeof(uint16_t);
                    542:                                le16enc(tic->strs.buf + tic->strs.bufpos,
                    543:                                    buf.bufpos);
                    544:                                tic->strs.bufpos += sizeof(uint16_t);
                    545:                                memcpy(tic->strs.buf + tic->strs.bufpos,
                    546:                                    buf.buf, buf.bufpos);
                    547:                                tic->strs.bufpos += buf.bufpos;
                    548:                                tic->strs.entries++;
                    549:                        }
                    550:                        continue;
                    551:                }
                    552:
                    553:                /* num cap */
                    554:                p = strchr(token, '#');
                    555:                if (p != NULL) {
                    556:                        *p++ = '\0';
                    557:                        /* Don't use the number if we already have it */
                    558:                        ind = _ti_numindex(token);
                    559:                        if (ind != -1 &&
                    560:                            _ti_find_cap(&tic->nums, 'n', ind) != NULL)
                    561:                                continue;
                    562:
1.5       roy       563:                        cnum = strtol(p, &e, 0);
1.1       roy       564:                        if (*e != '\0') {
                    565:                                dowarn(flags, "%s: %s: not a number",
                    566:                                    tic->name, token);
                    567:                                continue;
                    568:                        }
1.5       roy       569:                        if (!VALID_NUMERIC(cnum)) {
1.1       roy       570:                                dowarn(flags, "%s: %s: number out of range",
                    571:                                    tic->name, token);
                    572:                                continue;
                    573:                        }
1.5       roy       574:                        num = (short)cnum;
1.1       roy       575:                        if (ind == -1)
                    576:                                _ti_store_extra(tic, 1, token, 'n', -1,
                    577:                                    num, NULL, 0, flags);
                    578:                        else {
                    579:                                if (_ti_grow_tbuf(&tic->nums,
                    580:                                        sizeof(uint16_t) * 2) == NULL)
                    581:                                        goto error;
                    582:                                le16enc(tic->nums.buf + tic->nums.bufpos, ind);
                    583:                                tic->nums.bufpos += sizeof(uint16_t);
                    584:                                le16enc(tic->nums.buf + tic->nums.bufpos, num);
                    585:                                tic->nums.bufpos += sizeof(uint16_t);
                    586:                                tic->nums.entries++;
                    587:                        }
                    588:                        continue;
                    589:                }
                    590:
                    591:                flag = 1;
                    592:                len = strlen(token) - 1;
                    593:                if (token[len] == '@') {
                    594:                        flag = CANCELLED_BOOLEAN;
                    595:                        token[len] = '\0';
                    596:                }
                    597:                ind = _ti_flagindex(token);
                    598:                if (ind == -1 && flag == CANCELLED_BOOLEAN) {
                    599:                        if ((ind = _ti_numindex(token)) != -1) {
                    600:                                if (_ti_find_cap(&tic->nums, 'n', ind) != NULL)
                    601:                                        continue;
                    602:                                if (_ti_grow_tbuf(&tic->nums,
                    603:                                        sizeof(uint16_t) * 2) == NULL)
                    604:                                        goto error;
                    605:                                le16enc(tic->nums.buf + tic->nums.bufpos, ind);
                    606:                                tic->nums.bufpos += sizeof(uint16_t);
                    607:                                le16enc(tic->nums.buf + tic->nums.bufpos,
1.5       roy       608:                                        (uint16_t)CANCELLED_NUMERIC);
1.1       roy       609:                                tic->nums.bufpos += sizeof(uint16_t);
                    610:                                tic->nums.entries++;
                    611:                                continue;
                    612:                        } else if ((ind = _ti_strindex(token)) != -1) {
                    613:                                if (_ti_find_cap(&tic->strs, 's', ind) != NULL)
                    614:                                        continue;
                    615:                                if (_ti_grow_tbuf(&tic->strs,
                    616:                                        (sizeof(uint16_t) * 2) + 1) == NULL)
                    617:                                        goto error;
                    618:                                le16enc(tic->strs.buf + tic->strs.bufpos, ind);
                    619:                                tic->strs.bufpos += sizeof(uint16_t);
                    620:                                le16enc(tic->strs.buf + tic->strs.bufpos, 0);
                    621:                                tic->strs.bufpos += sizeof(uint16_t);
                    622:                                tic->strs.entries++;
                    623:                                continue;
                    624:                        }
                    625:                }
                    626:                if (ind == -1)
                    627:                        _ti_store_extra(tic, 1, token, 'f', flag, 0, NULL, 0,
                    628:                            flags);
                    629:                else if (_ti_find_cap(&tic->flags, 'f', ind) == NULL) {
                    630:                        if (_ti_grow_tbuf(&tic->flags, sizeof(uint16_t) + 1)
                    631:                            == NULL)
                    632:                                goto error;
                    633:                        le16enc(tic->flags.buf + tic->flags.bufpos, ind);
                    634:                        tic->flags.bufpos += sizeof(uint16_t);
                    635:                        tic->flags.buf[tic->flags.bufpos++] = flag;
                    636:                        tic->flags.entries++;
                    637:                }
                    638:        }
                    639:
                    640:        free(buf.buf);
                    641:        return tic;
                    642:
                    643: error:
                    644:        free(buf.buf);
                    645:        _ti_freetic(tic);
                    646:        return NULL;
                    647: }
                    648:
                    649: void
                    650: _ti_freetic(TIC *tic)
                    651: {
                    652:
                    653:        if (tic != NULL) {
                    654:                free(tic->name);
                    655:                free(tic->alias);
                    656:                free(tic->desc);
1.6.2.1 ! riz       657:                free(tic->extras.buf);
1.1       roy       658:                free(tic->flags.buf);
                    659:                free(tic->nums.buf);
                    660:                free(tic->strs.buf);
                    661:                free(tic);
                    662:        }
                    663: }

CVSweb <webmaster@jp.NetBSD.org>