Annotation of mandoc/term.c, Revision 1.1
1.1 ! kristaps 1: /* $Id: tree.c,v 1.2 2009/01/17 14:04:25 kristaps Exp $ */
! 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: */
! 19: #include <assert.h>
! 20: #include <curses.h>
! 21: #include <err.h>
! 22: #include <stdlib.h>
! 23: #include <stdio.h>
! 24: #include <string.h>
! 25: #include <term.h>
! 26: #include <unistd.h>
! 27:
! 28: #include "mdoc.h"
! 29:
! 30:
! 31: static int termprint_r(size_t, size_t,
! 32: const struct mdoc_node *);
! 33: static void termprint_head(size_t,
! 34: const struct mdoc_meta *);
! 35: static void termprint_tail(size_t,
! 36: const struct mdoc_meta *);
! 37:
! 38: static char *arch2a(enum mdoc_arch);
! 39: static char *vol2a(enum mdoc_vol);
! 40: static char *msec2a(enum mdoc_msec);
! 41:
! 42: static size_t ttitle2a(char *, enum mdoc_vol, enum mdoc_msec,
! 43: enum mdoc_arch, size_t);
! 44:
! 45:
! 46: static char *
! 47: arch2a(enum mdoc_arch arch)
! 48: {
! 49:
! 50: switch (arch) {
! 51: case (ARCH_alpha):
! 52: return("Alpha");
! 53: case (ARCH_amd64):
! 54: return("AMD64");
! 55: case (ARCH_amiga):
! 56: return("Amiga");
! 57: case (ARCH_arc):
! 58: return("ARC");
! 59: case (ARCH_arm):
! 60: return("ARM");
! 61: case (ARCH_armish):
! 62: return("ARMISH");
! 63: case (ARCH_aviion):
! 64: return("AViion");
! 65: case (ARCH_hp300):
! 66: return("HP300");
! 67: case (ARCH_hppa):
! 68: return("HPPA");
! 69: case (ARCH_hppa64):
! 70: return("HPPA64");
! 71: case (ARCH_i386):
! 72: return("i386");
! 73: case (ARCH_landisk):
! 74: return("LANDISK");
! 75: case (ARCH_luna88k):
! 76: return("Luna88k");
! 77: case (ARCH_mac68k):
! 78: return("Mac68k");
! 79: case (ARCH_macppc):
! 80: return("MacPPC");
! 81: case (ARCH_mvme68k):
! 82: return("MVME68k");
! 83: case (ARCH_mvme88k):
! 84: return("MVME88k");
! 85: case (ARCH_mvmeppc):
! 86: return("MVMEPPC");
! 87: case (ARCH_pmax):
! 88: return("PMAX");
! 89: case (ARCH_sgi):
! 90: return("SGI");
! 91: case (ARCH_socppc):
! 92: return("SOCPPC");
! 93: case (ARCH_sparc):
! 94: return("SPARC");
! 95: case (ARCH_sparc64):
! 96: return("SPARC64");
! 97: case (ARCH_sun3):
! 98: return("Sun3");
! 99: case (ARCH_vax):
! 100: return("VAX");
! 101: case (ARCH_zaurus):
! 102: return("Zaurus");
! 103: default:
! 104: break;
! 105: }
! 106:
! 107: return(NULL);
! 108: }
! 109:
! 110:
! 111: static char *
! 112: vol2a(enum mdoc_vol vol)
! 113: {
! 114:
! 115: switch (vol) {
! 116: case (VOL_AMD):
! 117: return("OpenBSD Ancestral Manual Documents");
! 118: case (VOL_IND):
! 119: return("OpenBSD Manual Master Index");
! 120: case (VOL_KM):
! 121: return("OpenBSD Kernel Manual");
! 122: case (VOL_LOCAL):
! 123: return("OpenBSD Local Manual");
! 124: case (VOL_PRM):
! 125: return("OpenBSD Programmer's Manual");
! 126: case (VOL_PS1):
! 127: return("OpenBSD Programmer's Supplementary Documents");
! 128: case (VOL_SMM):
! 129: return("OpenBSD System Manager's Manual");
! 130: case (VOL_URM):
! 131: return("OpenBSD Reference Manual");
! 132: case (VOL_USD):
! 133: return("OpenBSD User's Supplementary Documents");
! 134: default:
! 135: break;
! 136: }
! 137:
! 138: return(NULL);
! 139: }
! 140:
! 141:
! 142: static char *
! 143: msec2a(enum mdoc_msec msec)
! 144: {
! 145:
! 146: switch (msec) {
! 147: case(MSEC_1):
! 148: return("1");
! 149: case(MSEC_2):
! 150: return("2");
! 151: case(MSEC_3):
! 152: return("3");
! 153: case(MSEC_3f):
! 154: return("3f");
! 155: case(MSEC_3p):
! 156: return("3p");
! 157: case(MSEC_4):
! 158: return("4");
! 159: case(MSEC_5):
! 160: return("5");
! 161: case(MSEC_6):
! 162: return("6");
! 163: case(MSEC_7):
! 164: return("7");
! 165: case(MSEC_8):
! 166: return("8");
! 167: case(MSEC_9):
! 168: return("9");
! 169: case(MSEC_X11):
! 170: return("X11");
! 171: case(MSEC_X11R6):
! 172: return("X11R6");
! 173: case(MSEC_local):
! 174: return("local");
! 175: case(MSEC_n):
! 176: return("n");
! 177: case(MSEC_unass):
! 178: /* FALLTHROUGH */
! 179: case(MSEC_draft):
! 180: return("draft");
! 181: case(MSEC_paper):
! 182: return("paper");
! 183: default:
! 184: break;
! 185: }
! 186: return(NULL);
! 187: }
! 188:
! 189:
! 190: static size_t
! 191: ttitle2a(char *dst, enum mdoc_vol vol, enum mdoc_msec msec,
! 192: enum mdoc_arch arch, size_t sz)
! 193: {
! 194: char *p;
! 195: size_t ssz;
! 196:
! 197: if (NULL == (p = vol2a(vol)))
! 198: switch (msec) {
! 199: case (MSEC_1):
! 200: /* FALLTHROUGH */
! 201: case (MSEC_6):
! 202: /* FALLTHROUGH */
! 203: case (MSEC_7):
! 204: p = vol2a(VOL_URM);
! 205: break;
! 206: case (MSEC_8):
! 207: p = vol2a(VOL_SMM);
! 208: break;
! 209: case (MSEC_2):
! 210: /* FALLTHROUGH */
! 211: case (MSEC_3):
! 212: /* FALLTHROUGH */
! 213: case (MSEC_4):
! 214: /* FALLTHROUGH */
! 215: case (MSEC_5):
! 216: p = vol2a(VOL_PRM);
! 217: break;
! 218: case (MSEC_9):
! 219: p = vol2a(VOL_KM);
! 220: break;
! 221: default:
! 222: /* FIXME: capitalise. */
! 223: if (NULL == (p = msec2a(msec)))
! 224: p = msec2a(MSEC_local);
! 225: break;
! 226: }
! 227: assert(p);
! 228:
! 229: if ((ssz = strlcpy(dst, p, sz)) >= sz)
! 230: return(ssz);
! 231:
! 232: if ((p = arch2a(arch))) {
! 233: if ((ssz = strlcat(dst, " (", sz)) >= sz)
! 234: return(ssz);
! 235: if ((ssz = strlcat(dst, p, sz)) >= sz)
! 236: return(ssz);
! 237: if ((ssz = strlcat(dst, ")", sz)) >= sz)
! 238: return(ssz);
! 239: }
! 240:
! 241: return(ssz);
! 242: }
! 243:
! 244:
! 245: static int
! 246: termprint_r(size_t cols, size_t indent, const struct mdoc_node *node)
! 247: {
! 248:
! 249: return(1);
! 250: }
! 251:
! 252:
! 253: static void
! 254: termprint_tail(size_t cols, const struct mdoc_meta *meta)
! 255: {
! 256: struct tm *tm;
! 257: char *buf, *os;
! 258: size_t sz, osz, ssz, i;
! 259:
! 260: if (NULL == (buf = malloc(cols)))
! 261: err(1, "malloc");
! 262: if (NULL == (os = malloc(cols)))
! 263: err(1, "malloc");
! 264:
! 265: tm = localtime(&meta->date);
! 266: if (NULL == strftime(buf, cols, "%B %d, %Y", tm))
! 267: err(1, "strftime");
! 268:
! 269: osz = strlcpy(os, meta->os, cols);
! 270:
! 271: sz = strlen(buf);
! 272: ssz = sz + osz + 1;
! 273:
! 274: if (ssz > cols) {
! 275: ssz -= cols;
! 276: assert(ssz <= osz);
! 277: os[osz - ssz] = 0;
! 278: ssz = 1;
! 279: } else
! 280: ssz = cols - ssz + 1;
! 281:
! 282: printf("%s", os);
! 283: for (i = 0; i < ssz; i++)
! 284: printf(" ");
! 285:
! 286: printf("%s\n", buf);
! 287:
! 288: free(buf);
! 289: free(os);
! 290: }
! 291:
! 292:
! 293: static void
! 294: termprint_head(size_t cols, const struct mdoc_meta *meta)
! 295: {
! 296: char *msec, *buf, *title;
! 297: size_t ssz, tsz, ttsz, i;
! 298:
! 299: if (NULL == (buf = malloc(cols)))
! 300: err(1, "malloc");
! 301: if (NULL == (title = malloc(cols)))
! 302: err(1, "malloc");
! 303:
! 304: /* Format the manual page header. */
! 305:
! 306: tsz = ttitle2a(buf, meta->vol, meta->msec, meta->arch, cols);
! 307: ttsz = strlcpy(title, meta->title, cols);
! 308:
! 309: if (NULL == (msec = msec2a(meta->msec)))
! 310: msec = "";
! 311:
! 312: ssz = (2 * (ttsz + 2 + strlen(msec))) + tsz + 2;
! 313:
! 314: if (ssz > cols) {
! 315: if ((ssz -= cols) % 2)
! 316: ssz++;
! 317: ssz /= 2;
! 318:
! 319: assert(ssz <= ttsz);
! 320: title[ttsz - ssz] = 0;
! 321: ssz = 1;
! 322: } else
! 323: ssz = ((cols - ssz) / 2) + 1;
! 324:
! 325: printf("%s(%s)", title, msec);
! 326:
! 327: for (i = 0; i < ssz; i++)
! 328: printf(" ");
! 329:
! 330: printf("%s", buf);
! 331:
! 332: for (i = 0; i < ssz; i++)
! 333: printf(" ");
! 334:
! 335: printf("%s(%s)\n\n", title, msec);
! 336:
! 337: free(title);
! 338: free(buf);
! 339: }
! 340:
! 341:
! 342: int
! 343: termprint(const struct mdoc_node *node,
! 344: const struct mdoc_meta *meta)
! 345: {
! 346: size_t cols;
! 347:
! 348: if (ERR == setupterm(NULL, STDOUT_FILENO, NULL))
! 349: return(0);
! 350:
! 351: cols = columns < 60 ? 60 : (size_t)columns;
! 352:
! 353: termprint_head(cols, meta);
! 354: if ( ! termprint_r(cols, 0, node))
! 355: return(0);
! 356: termprint_tail(cols, meta);
! 357: return(1);
! 358: }
! 359:
! 360:
CVSweb