[BACK]Return to strings.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Annotation of mandoc/strings.c, Revision 1.30

1.30    ! kristaps    1: /* $Id: strings.c,v 1.29 2009/03/14 05:36:07 kristaps Exp $ */
1.1       kristaps    2: /*
                      3:  * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the
                      7:  * above copyright notice and this permission notice appear in all
                      8:  * copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
                     11:  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
                     12:  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
                     13:  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
                     14:  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
                     15:  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
                     16:  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
                     17:  * PERFORMANCE OF THIS SOFTWARE.
                     18:  */
1.27      kristaps   19: #include <sys/types.h>
                     20:
1.1       kristaps   21: #include <assert.h>
                     22: #include <ctype.h>
                     23: #include <stdlib.h>
                     24: #include <stdio.h>
1.2       kristaps   25: #include <string.h>
1.1       kristaps   26:
1.26      kristaps   27: #include "private.h"
                     28:
1.14      kristaps   29: /*
1.26      kristaps   30:  * Various string-literal operations:  converting scalars to and from
                     31:  * strings, etc.
1.14      kristaps   32:  */
                     33:
1.26      kristaps   34: struct mdoc_secname {
                     35:        const char      *name;
                     36:        int              flag;
                     37: #define        MSECNAME_META   (1 << 0)
                     38: };
                     39:
                     40: /* Section names corresponding to mdoc_sec. */
                     41:
                     42: static const struct mdoc_secname secnames[] = {
                     43:        { "PROLOGUE", MSECNAME_META },
                     44:        { "BODY", MSECNAME_META },
                     45:        { "NAME", 0 },
                     46:        { "LIBRARY", 0 },
                     47:        { "SYNOPSIS", 0 },
                     48:        { "DESCRIPTION", 0 },
                     49:        { "IMPLEMENTATION NOTES", 0 },
                     50:        { "RETURN VALUES", 0 },
                     51:        { "ENVIRONMENT", 0 },
                     52:        { "FILES", 0 },
                     53:        { "EXAMPLES", 0 },
                     54:        { "DIAGNOSTICS", 0 },
                     55:        { "COMPATIBILITY", 0 },
                     56:        { "ERRORS", 0 },
                     57:        { "SEE ALSO", 0 },
                     58:        { "STANDARDS", 0 },
                     59:        { "HISTORY", 0 },
                     60:        { "AUTHORS", 0 },
                     61:        { "CAVEATS", 0 },
                     62:        { "BUGS", 0 },
                     63:        { NULL, 0 }
                     64: };
1.1       kristaps   65:
1.4       kristaps   66: #ifdef __linux__
                     67: extern char            *strptime(const char *, const char *, struct tm *);
                     68: #endif
                     69:
1.16      kristaps   70:
                     71: size_t
                     72: mdoc_isescape(const char *p)
                     73: {
                     74:        size_t           c;
                     75:
                     76:        if ('\\' != *p++)
                     77:                return(0);
                     78:
                     79:        switch (*p) {
                     80:        case ('\\'):
                     81:                /* FALLTHROUGH */
                     82:        case ('\''):
                     83:                /* FALLTHROUGH */
                     84:        case ('`'):
                     85:                /* FALLTHROUGH */
1.28      kristaps   86:        case ('q'):
                     87:                /* FALLTHROUGH */
1.16      kristaps   88:        case ('-'):
                     89:                /* FALLTHROUGH */
                     90:        case (' '):
                     91:                /* FALLTHROUGH */
1.29      kristaps   92:        case ('|'):
                     93:                /* FALLTHROUGH */
1.17      kristaps   94:        case ('&'):
                     95:                /* FALLTHROUGH */
1.16      kristaps   96:        case ('.'):
                     97:                /* FALLTHROUGH */
1.30    ! kristaps   98:        case (':'):
        !            99:                /* FALLTHROUGH */
1.16      kristaps  100:        case ('e'):
                    101:                return(2);
1.21      kristaps  102:        case ('*'):
1.25      kristaps  103:                if (0 == *++p || ! isgraph((u_char)*p))
1.21      kristaps  104:                        return(0);
                    105:                switch (*p) {
                    106:                case ('('):
1.25      kristaps  107:                        if (0 == *++p || ! isgraph((u_char)*p))
1.21      kristaps  108:                                return(0);
                    109:                        return(4);
1.24      kristaps  110:                case ('['):
                    111:                        for (c = 3, p++; *p && ']' != *p; p++, c++)
1.25      kristaps  112:                                if ( ! isgraph((u_char)*p))
1.24      kristaps  113:                                        break;
                    114:                        return(*p == ']' ? c : 0);
1.21      kristaps  115:                default:
                    116:                        break;
                    117:                }
                    118:                return(3);
1.16      kristaps  119:        case ('('):
1.25      kristaps  120:                if (0 == *++p || ! isgraph((u_char)*p))
1.16      kristaps  121:                        return(0);
1.25      kristaps  122:                if (0 == *++p || ! isgraph((u_char)*p))
1.16      kristaps  123:                        return(0);
                    124:                return(4);
                    125:        case ('['):
                    126:                break;
                    127:        default:
                    128:                return(0);
                    129:        }
                    130:
                    131:        for (c = 3, p++; *p && ']' != *p; p++, c++)
1.25      kristaps  132:                if ( ! isgraph((u_char)*p))
1.16      kristaps  133:                        break;
                    134:
                    135:        return(*p == ']' ? c : 0);
                    136: }
                    137:
                    138:
1.1       kristaps  139: int
1.3       kristaps  140: mdoc_iscdelim(char p)
1.1       kristaps  141: {
                    142:
1.3       kristaps  143:        switch (p) {
1.1       kristaps  144:        case('.'):
                    145:                /* FALLTHROUGH */
                    146:        case(','):
                    147:                /* FALLTHROUGH */
                    148:        case(';'):
                    149:                /* FALLTHROUGH */
                    150:        case(':'):
                    151:                /* FALLTHROUGH */
                    152:        case('?'):
                    153:                /* FALLTHROUGH */
                    154:        case('!'):
                    155:                /* FALLTHROUGH */
                    156:        case('('):
                    157:                /* FALLTHROUGH */
                    158:        case(')'):
                    159:                /* FALLTHROUGH */
                    160:        case('['):
                    161:                /* FALLTHROUGH */
                    162:        case(']'):
                    163:                /* FALLTHROUGH */
1.7       kristaps  164:        case('{'):
                    165:                /* FALLTHROUGH */
1.1       kristaps  166:        case('}'):
                    167:                return(1);
                    168:        default:
                    169:                break;
                    170:        }
                    171:
                    172:        return(0);
                    173: }
                    174:
1.2       kristaps  175:
1.3       kristaps  176: int
                    177: mdoc_isdelim(const char *p)
                    178: {
                    179:
                    180:        if (0 == *p)
                    181:                return(0);
                    182:        if (0 != *(p + 1))
                    183:                return(0);
                    184:        return(mdoc_iscdelim(*p));
                    185: }
                    186:
                    187:
1.2       kristaps  188: enum mdoc_sec
1.9       kristaps  189: mdoc_atosec(const char *p)
1.2       kristaps  190: {
1.26      kristaps  191:        const struct mdoc_secname *n;
                    192:        int                        i;
1.2       kristaps  193:
1.26      kristaps  194:        for (i = 0, n = secnames; n->name; n++, i++)
                    195:                if ( ! (n->flag & MSECNAME_META))
                    196:                        if (xstrcmp(p, n->name))
                    197:                                return((enum mdoc_sec)i);
1.2       kristaps  198:
                    199:        return(SEC_CUSTOM);
                    200: }
                    201:
                    202:
                    203: time_t
                    204: mdoc_atotime(const char *p)
                    205: {
                    206:        struct tm        tm;
1.11      kristaps  207:        char            *pp;
1.2       kristaps  208:
1.5       kristaps  209:        (void)memset(&tm, 0, sizeof(struct tm));
                    210:
1.11      kristaps  211:        if (xstrcmp(p, "$Mdocdate$"))
                    212:                return(time(NULL));
                    213:        if ((pp = strptime(p, "$Mdocdate: %b %d %Y $", &tm)) && 0 == *pp)
1.2       kristaps  214:                return(mktime(&tm));
1.11      kristaps  215:        /* XXX - this matches "June 1999", which is wrong. */
                    216:        if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
                    217:                return(mktime(&tm));
                    218:        if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
1.2       kristaps  219:                return(mktime(&tm));
                    220:
                    221:        return(0);
                    222: }
                    223:
                    224:
1.20      kristaps  225: size_t
                    226: mdoc_macro2len(int macro)
                    227: {
                    228:
                    229:        switch (macro) {
                    230:        case(MDOC_Ad):
                    231:                return(12);
                    232:        case(MDOC_Ao):
                    233:                return(12);
                    234:        case(MDOC_An):
                    235:                return(12);
                    236:        case(MDOC_Aq):
                    237:                return(12);
                    238:        case(MDOC_Ar):
                    239:                return(12);
                    240:        case(MDOC_Bo):
                    241:                return(12);
                    242:        case(MDOC_Bq):
                    243:                return(12);
                    244:        case(MDOC_Cd):
                    245:                return(12);
                    246:        case(MDOC_Cm):
                    247:                return(10);
                    248:        case(MDOC_Do):
                    249:                return(10);
                    250:        case(MDOC_Dq):
                    251:                return(12);
                    252:        case(MDOC_Dv):
                    253:                return(12);
                    254:        case(MDOC_Eo):
                    255:                return(12);
                    256:        case(MDOC_Em):
                    257:                return(10);
                    258:        case(MDOC_Er):
                    259:                return(12);
                    260:        case(MDOC_Ev):
                    261:                return(15);
                    262:        case(MDOC_Fa):
                    263:                return(12);
                    264:        case(MDOC_Fl):
                    265:                return(10);
                    266:        case(MDOC_Fo):
                    267:                return(16);
                    268:        case(MDOC_Fn):
                    269:                return(16);
                    270:        case(MDOC_Ic):
                    271:                return(10);
                    272:        case(MDOC_Li):
                    273:                return(16);
                    274:        case(MDOC_Ms):
                    275:                return(6);
                    276:        case(MDOC_Nm):
                    277:                return(10);
                    278:        case(MDOC_No):
                    279:                return(12);
                    280:        case(MDOC_Oo):
                    281:                return(10);
                    282:        case(MDOC_Op):
                    283:                return(14);
                    284:        case(MDOC_Pa):
                    285:                return(32);
                    286:        case(MDOC_Pf):
                    287:                return(12);
                    288:        case(MDOC_Po):
                    289:                return(12);
                    290:        case(MDOC_Pq):
                    291:                return(12);
                    292:        case(MDOC_Ql):
                    293:                return(16);
                    294:        case(MDOC_Qo):
                    295:                return(12);
                    296:        case(MDOC_So):
                    297:                return(12);
                    298:        case(MDOC_Sq):
                    299:                return(12);
                    300:        case(MDOC_Sy):
                    301:                return(6);
                    302:        case(MDOC_Sx):
                    303:                return(16);
                    304:        case(MDOC_Tn):
                    305:                return(10);
                    306:        case(MDOC_Va):
                    307:                return(12);
                    308:        case(MDOC_Vt):
                    309:                return(12);
                    310:        case(MDOC_Xr):
                    311:                return(10);
                    312:        default:
                    313:                break;
                    314:        };
                    315:        return(0);
                    316: }

CVSweb