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

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

CVSweb <webmaster@jp.NetBSD.org>