Annotation of mandoc/ml.c, Revision 1.9
1.9 ! kristaps 1: /* $Id: ml.c,v 1.8 2008/12/09 17:09:12 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.5 kristaps 19: #include <assert.h>
1.1 kristaps 20: #include <stdlib.h>
21: #include <string.h>
22:
1.2 kristaps 23: #include "ml.h"
1.1 kristaps 24:
1.2 kristaps 25: #ifdef __linux__
26: extern size_t strlcat(char *, const char *, size_t);
27: extern size_t strlcpy(char *, const char *, size_t);
28: #endif
1.1 kristaps 29:
30:
1.2 kristaps 31: int
1.6 kristaps 32: ml_putstring(struct md_mbuf *p, const char *buf, size_t *pos)
33: {
34:
35: return(ml_nputstring(p, buf, strlen(buf), pos));
36: }
37:
38:
39: int
1.2 kristaps 40: ml_nputstring(struct md_mbuf *p,
41: const char *buf, size_t sz, size_t *pos)
1.1 kristaps 42: {
1.5 kristaps 43: int i, v;
1.4 kristaps 44: const char *seq;
45: size_t ssz;
1.1 kristaps 46:
1.2 kristaps 47: for (i = 0; i < (int)sz; i++) {
1.1 kristaps 48: switch (buf[i]) {
1.4 kristaps 49:
1.5 kristaps 50: /* Escaped value. */
51: case ('\\'):
1.7 kristaps 52: if (-1 == (v = rofftok_scan(buf, &i)))
1.5 kristaps 53: return(0);
54:
55: switch (v) {
56: case (ROFFTok_Sp_A):
57: seq = "\\a";
58: ssz = 2;
59: break;
60: case (ROFFTok_Sp_B):
61: seq = "\\b";
62: ssz = 2;
63: break;
64: case (ROFFTok_Sp_F):
65: seq = "\\f";
66: ssz = 2;
67: break;
68: case (ROFFTok_Sp_N):
69: seq = "\\n";
70: ssz = 2;
71: break;
72: case (ROFFTok_Sp_R):
73: seq = "\\r";
74: ssz = 2;
75: break;
76: case (ROFFTok_Sp_T):
77: seq = "\\t";
78: ssz = 2;
79: break;
80: case (ROFFTok_Sp_V):
81: seq = "\\v";
82: ssz = 2;
83: break;
84: case (ROFFTok_Sp_0):
85: seq = "\\0";
86: ssz = 2;
87: break;
88: case (ROFFTok_Space):
89: seq = " ";
90: ssz = 6;
91: break;
92: case (ROFFTok_Hyphen):
93: seq = "‐";
94: ssz = 7;
95: break;
96: case (ROFFTok_Em):
97: seq = "—";
98: ssz = 7;
99: break;
100: case (ROFFTok_En):
101: seq = "–";
102: ssz = 7;
103: break;
104: case (ROFFTok_Ge):
105: seq = "≥";
106: ssz = 7;
107: break;
108: case (ROFFTok_Le):
109: seq = "≤";
110: ssz = 7;
111: break;
112: case (ROFFTok_Rquote):
113: seq = "”";
114: ssz = 7;
115: break;
116: case (ROFFTok_Lquote):
117: seq = "“";
118: ssz = 7;
119: break;
120: case (ROFFTok_Uparrow):
121: seq = "↑";
122: ssz = 7;
123: break;
124: case (ROFFTok_Acute):
125: seq = "´";
126: ssz = 6;
127: break;
128: case (ROFFTok_Grave):
129: seq = "`";
130: ssz = 5;
131: break;
132: case (ROFFTok_Pi):
133: seq = "π";
134: ssz = 6;
135: break;
136: case (ROFFTok_Ne):
137: seq = "≠";
138: ssz = 7;
139: break;
140: case (ROFFTok_Lt):
141: seq = "<";
142: ssz = 4;
143: break;
144: case (ROFFTok_Gt):
145: seq = ">";
146: ssz = 4;
147: break;
148: case (ROFFTok_Plusmin):
149: seq = "±";
150: ssz = 6;
151: break;
152: case (ROFFTok_Infty):
153: seq = "∞";
154: ssz = 7;
155: break;
156: case (ROFFTok_Bar):
157: seq = "|";
158: ssz = 6;
159: break;
160: case (ROFFTok_Nan):
161: seq = "Nan";
162: ssz = 3;
163: break;
164: case (ROFFTok_Quote):
165: seq = """;
166: ssz = 6;
167: break;
168: case (ROFFTok_Slash):
169: seq = "\\";
170: ssz = 1;
171: break;
172: case (ROFFTok_Null):
173: seq = "";
174: ssz = 0;
175: break;
176: default:
1.7 kristaps 177: return(0);
1.5 kristaps 178: }
179: break;
180:
1.4 kristaps 181: /* Ampersand ml-escape. */
1.1 kristaps 182: case ('&'):
1.4 kristaps 183: seq = "&";
184: ssz = 5;
1.1 kristaps 185: break;
1.4 kristaps 186:
187: /* Quotation ml-escape. */
1.1 kristaps 188: case ('"'):
1.4 kristaps 189: seq = """;
190: ssz = 6;
1.1 kristaps 191: break;
1.4 kristaps 192:
193: /* Lt ml-escape. */
1.1 kristaps 194: case ('<'):
1.4 kristaps 195: seq = "<";
196: ssz = 4;
1.1 kristaps 197: break;
1.4 kristaps 198:
199: /* Gt ml-escape. */
1.1 kristaps 200: case ('>'):
1.4 kristaps 201: seq = ">";
202: ssz = 4;
1.1 kristaps 203: break;
1.4 kristaps 204:
1.1 kristaps 205: default:
1.4 kristaps 206: seq = &buf[i];
207: ssz = 1;
1.1 kristaps 208: break;
209: }
1.4 kristaps 210:
1.5 kristaps 211: if (ssz > 0 && ! ml_nputs(p, seq, ssz, pos))
1.4 kristaps 212: return(-1);
1.1 kristaps 213: }
1.2 kristaps 214: return(1);
1.1 kristaps 215: }
216:
217:
1.2 kristaps 218: int
219: ml_nputs(struct md_mbuf *p, const char *buf, size_t sz, size_t *pos)
1.1 kristaps 220: {
221:
1.4 kristaps 222: if (0 == sz)
223: return(1);
224:
1.2 kristaps 225: if ( ! md_buf_puts(p, buf, sz))
226: return(0);
227:
1.7 kristaps 228: if (pos)
229: *pos += sz;
1.2 kristaps 230: return(1);
1.1 kristaps 231: }
232:
233:
1.2 kristaps 234: int
1.3 kristaps 235: ml_puts(struct md_mbuf *p, const char *buf, size_t *pos)
236: {
237: size_t sz;
238:
1.4 kristaps 239: if (0 == (sz = strlen(buf)))
240: return(1);
241:
1.3 kristaps 242: if ( ! md_buf_puts(p, buf, sz))
243: return(0);
1.7 kristaps 244:
245: if (pos)
246: *pos += sz;
1.3 kristaps 247: return(1);
248: }
249:
250:
251: int
1.2 kristaps 252: ml_putchars(struct md_mbuf *p, char buf, size_t count, size_t *pos)
1.1 kristaps 253: {
254: size_t i;
255:
1.2 kristaps 256: for (i = 0; i < count; i++)
257: if ( ! ml_nputs(p, &buf, 1, pos))
258: return(0);
1.1 kristaps 259:
1.2 kristaps 260: return(1);
1.1 kristaps 261: }
CVSweb