1 /*****************************************************************************/
2 /*                                                                           */
3 /*                 (C)  Copyright 1997      Alberto Pasquale                 */
4 /*                 Portions (C) Copyright 1999 Per Lundberg                  */
5 /*                                                                           */
6 /*                   A L L   R I G H T S   R E S E R V E D                   */
7 /*                                                                           */
8 /*****************************************************************************/
9 /*                                                                           */
10 /* How to contact the author:  Alberto Pasquale of 2:332/504@fidonet         */
11 /*                             Viale Verdi 106                               */
12 /*                             41100 Modena                                  */
13 /*                             Italy                                         */
14 /*                                                                           */
15 /*****************************************************************************/
16 
17 #include <string.h>
18 
19 #include "apgenlib.hpp"
20 #include "apgenlb2.hpp"
21 
22 #define InString    1   // for CleanLine status
23 #define OutString   2
24 #define LineEnd     3
25 
26 const char *tkp = NULL;
27 
CleanLine(char * line)28 static void CleanLine (char *line)    // Get rid of tabs, comments, newline.
29 {                              // Preserve ';' if enclosed in string.
30     int status = OutString;    // Remove trailing space.
31     char *c = line;
32 
33     while (status != LineEnd) {
34         switch (*c) {
35             case '\t':      // convert tab to blank
36                 *c = ' ';
37                 break;
38 
39             case '\n':
40             case '\0':
41                 status = LineEnd;
42                 continue;
43 
44             case '\"':
45                 if (status == InString) {
46                     if (*(c+1) == '\"')
47                         c++;
48                     else
49                         status = OutString;
50                 } else
51                     status = InString;
52                 break;
53 
54             case ';' :
55                 if (status == OutString) {
56                     status = LineEnd;
57                     continue;
58                 }
59         }
60         c++;
61     }
62 
63     while (c > line)            // remove trailing space
64         if (*(c-1) == ' ')
65             c--;
66         else
67             break;
68 
69     *c = '\0';
70 }
71 
72 
CfgFile(int lsize)73 CfgFile::CfgFile (int lsize)
74 {
75     f = NULL;
76     lbuff = new char[lsize];
77     token = new char[lsize];
78     lbuff[0] = '\0';
79     nextc = lbuff;
80     CfgFile::lsize = lsize;
81 }
82 
83 
~CfgFile()84 CfgFile::~CfgFile ()
85 {
86     delete[] token;
87     delete[] lbuff;
88     if (f)
89         Close ();
90 }
91 
92 
Open(pcsz filename)93 int CfgFile::Open (pcsz filename)
94 {
95     if (f)
96         return 1;
97     f = fopen (filename, "rt");
98     if (!f)
99         return -1;
100     l = 0;
101     return 0;
102 }
103 
Close()104 int CfgFile::Close ()
105 {
106     if (!f)
107         return -1;
108 
109     int ret = fclose (f);
110     f = NULL;
111     return ret;
112 }
113 
GetLn()114 pcsz CfgFile::GetLn ()
115 {
116     do {
117         char *res = fgets (lbuff, lsize, f);
118         if (!res)
119           return NULL;
120         l++;
121         CleanLine (lbuff);  /* get rid of tabs, comments and newline */
122         nextc = lbuff;
123         tkp = TokenPtr ();
124     } while (!tkp);
125 
126     return tkp;
127 }
128 
ReGetLn()129 pcsz CfgFile::ReGetLn ()                // As previous GetLn; no effect on GetToken
130 {
131   return tkp;
132 }
133 
GetToken()134 pcsz CfgFile::GetToken ()
135 {
136     if (*nextc == '\0')                 // no more tokens !
137         return NULL;
138 
139     if (GetName (nextc, token, lsize) < 0)
140         return NULL;                       // error
141 
142     return token;                       // can be empty string !
143 }
144 
ReGetToken()145 pcsz CfgFile::ReGetToken ()             // As previous GetToken
146 {
147     return token;
148 }
149 
TokenPtr()150 pcsz CfgFile::TokenPtr ()
151 {
152     while (*nextc == ' ')       // skip space
153         nextc++;
154 
155     if (*nextc == '\0')
156         return NULL;
157 
158     return nextc;
159 }
160 
161 
LineN()162 uint CfgFile::LineN ()
163 {
164     return l;
165 }
166 
RestOfLine()167 pcsz CfgFile::RestOfLine ()	// start of next word, NullStr if EOL
168 {
169    if (nextc==NULL || *nextc == '\0')
170      return NULL;
171    return nextc;
172 }
173