1 /*****************************************************************************/
2 /* */
3 /* (C) Copyright 1991-1996 Alberto Pasquale */
4 /* */
5 /* A L L R I G H T S R E S E R V E D */
6 /* */
7 /*****************************************************************************/
8 /* */
9 /* This source code is NOT in the public domain and it CANNOT be used or */
10 /* distributed without written permission from the author. */
11 /* */
12 /*****************************************************************************/
13 /* */
14 /* How to contact the author: Alberto Pasquale of 2:332/504@fidonet */
15 /* Viale Verdi 106 */
16 /* 41100 Modena */
17 /* Italy */
18 /* */
19 /*****************************************************************************/
20
21 // OutWrap.Cpp
22
23 #ifdef __OS2__
24 #define INCL_DOS
25 #include <os2.h>
26 #endif
27 #include <apgenlib.hpp>
28 #include <string.h>
29 #include <stdlib.h>
30 #include "bbsgenlb.hpp"
31
32 #define WrapColOff 0
33 #define WrapEndOff 1023
34 #define WrapColDef 0
35 #define WrapEndDef 79
36
37
OutWrap(const char * WrapCfg)38 OutWrap::OutWrap (const char *WrapCfg)
39 {
40 OutWrap::WrapCfg = newcpy (WrapCfg);
41 wrapcol = WrapColOff;
42 wrapend = WrapEndOff;
43 CfgDone = FALSE;
44 LineBuf = NULL;
45 }
46
47
~OutWrap()48 OutWrap::~OutWrap ()
49 {
50 if (LineBuf)
51 delete[] LineBuf;
52 delete[] WrapCfg;
53 }
54
55
ParseCfg(const char * clnline)56 int OutWrap::ParseCfg (const char *clnline)
57 {
58 const char *tkp = clnline;
59 char *tok = GetStatName (tkp);
60
61 if (!tok)
62 return OWcfgNotFound;
63
64 if (stricmp (tok, WrapCfg) == 0) {
65 if (CfgDone)
66 return OWcfgDupe;
67 CfgDone = TRUE;
68 wrapcol = WrapColDef;
69 wrapend = WrapEndDef;
70 if ((tok = GetStatName (tkp)) != NULL) {
71 wrapcol = atoi (tok);
72 tok = GetStatName (tkp);
73 if (tok != NULL)
74 wrapend = atoi (tok);
75 }
76 if ((wrapend <= wrapcol) || (wrapcol < 0)) {
77 wrapcol = WrapColDef;
78 wrapend = WrapEndDef;
79 return OWcfgError;
80 }
81
82 return OWcfgFound;
83 }
84
85 return OWcfgNotFound;
86 }
87
88
n2wr(const char * b,int maxlen)89 static int n2wr (const char *b, int maxlen) // characters before wrap
90 {
91 int lnlen = strcspn (b, "\n");
92 if (maxlen >= lnlen) // full line shorter than maxlen
93 return lnlen;
94
95 const char *e = b + maxlen; // points after last allowable char
96 while ((*e != ' ') && (e > b))
97 e--;
98 if (*e != ' ') // long token: can't word wrap
99 return maxlen;
100
101 while ((*e == ' ') && (e > b))
102 e--;
103 if (*e == ' ') // long space: can't word wrap
104 return maxlen;
105
106 e++; // points after last character to output
107
108 return (int)(e-b);
109 }
110
111
fwrap(const char * src,int begin,OWShow ows,void * prm)112 int OutWrap::fwrap (const char *src, int begin, OWShow ows, void *prm)
113 { // return n written from b, EOF on error
114 const char *b = src;
115 int nspaces = begin ? 0 : wrapcol; // number of heading spaces
116 int maxlen = wrapend - nspaces; // size for remaining string
117 int nwr = n2wr (b, maxlen); // size of string to be copied
118
119 sprintf (LineBuf, "%*s%.*s", nspaces, "", nwr, b);
120 if (ows (LineBuf, prm))
121 return EOF;
122
123 b += nwr;
124 if ((*b == '\n') || (*b == ' '))
125 b ++;
126
127 return int (b - src);
128 }
129
130
Out(const char * source,OWShow ows,void * prm)131 int OutWrap::Out (const char *source, OWShow ows, void *prm)
132 {
133 if (!LineBuf)
134 LineBuf = new char[wrapend+1];
135
136 const char *b = source;
137
138 int nwr = fwrap (b, 1, ows, prm);
139 if (nwr == EOF)
140 return EOF;
141 b += nwr;
142
143 while (*b) {
144 nwr = fwrap (b, 0, ows, prm);
145 if (nwr == EOF)
146 return EOF;
147 b += nwr;
148 }
149
150 return 0;
151 }
152
153