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