Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtinfo / dtinfogen / infolib / etc / NCFGen.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: NCFGen.C /main/9 1996/08/21 15:47:02 drk $ */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #if !defined(__uxp__) && !defined(USL)
28 #include <strings.h>
29 #endif
30 #include <strstream.h>
31
32 #include "Exceptions.hh"
33 #include "DataBase.h"
34 #include "BookCaseDB.h"
35 #include "Task.h"
36 #include "Handler.h"
37 #include "StyleValidate.h"
38 #include "Token.h"
39
40 /* MMDB interfaces */
41 #include "oliasdb/mmdb.h"
42 #include "oliasdb/asciiIn_filters.h"
43 #include "oliasdb/olias_consts.h"
44 #include "oliasdb/stylesheet_hd.h"
45
46
47 /* Hash table interfaces */
48 #include "dti_cc/CC_String.h"
49 #include "dti_cc/cc_hdict.h"
50 #include "BTCollectable.h"
51
52 #ifdef FISH_DEBUG
53 #include "dbug.h"
54 #endif
55
56 #define SKIP_CODE -1
57 static unsigned hash_func(const CC_String &str)
58 {
59   return str.hash();
60 }
61
62 //-------------------------------------------------------------------------
63 static void
64 writeStyleSheets(BookCaseDB& db)
65 {
66   DBTable *out = db.DB::table(DATABASE_STDIO,
67                               STYLESHEET_CODE, BT_NUM_STYLESHEET_FIELDS,
68                               DB::CREATE);
69
70   DBTable *in = db.table(BookCaseDB::StyleSheet, DB::READ);
71   DBCursor cursor(*in);
72
73   const char *name;
74   const char *online;
75   int len_o;
76   const char *print;
77   int len_p;
78
79   int statusO = 0;
80   int statusP = 0;
81
82   
83   while(cursor.next(STRING_CODE, &name,
84                     -STRING_CODE, &online, &len_o,
85                     -STRING_CODE, &print, &len_p,
86                     NULL)){
87     if( statusO=validate_stylesheet( online, len_o, ONLINE )){
88       Token::signalError(Token::User, Token::Continuable, 0, 0,
89                          "Online style sheet for `%s' is invalid.", name);
90     }
91     
92     if( statusP=validate_stylesheet( print, len_p, PRINT )){
93       Token::signalError(Token::User, Token::Continuable, 0, 0,
94                          "Print style sheet for `%s' is invalid.", name);
95     }
96
97     if ( statusO || statusP ) {
98       throw(Unexpected("Style sheet validation failed\n"));
99     }
100     
101     out->insert(STRING_CODE, name,
102                 -STRING_CODE, online, len_o,
103                 -STRING_CODE, print, len_p,
104                 NULL);
105   }
106
107   delete out;
108 }
109
110
111 //-------------------------------------------------------------------------
112 static void
113 buildNCF(BookCaseDB& db, const char *base_name, int compressed)
114 {
115   DBTable *ncf = db.DB::table(DATABASE_STDIO,
116                               OLIAS_NODE_CODE, BT_NUM_OLIAS_NODE_FIELDS,
117                               DB::CREATE);
118
119   DBTable *nodeMeta = db.table(BookCaseDB::NodeMeta, DB::READ);
120   DBCursor cursor(*nodeMeta);
121
122
123   const char *bookLocator;
124   const char *nodeLocator;
125   const char *filename;
126   int         line_num;
127   const char *title;
128   const char *stitle;
129   const char *style;
130   int dupID = 0;
131
132   OLIAS_DB mmdb_handle;
133   info_lib *mmdb = 
134     mmdb_handle.openInfoLib(getenv("MMDB_PATH"), (char*)base_name);
135   info_base *base_ptr = mmdb->get_info_base(base_name);
136
137   const int BUFSIZE=30;
138
139   hashTable<CC_String,BTCollectable> node_dict(hash_func);    // Hash table...
140   
141   if ( compressed ) {
142
143     // 30 will be enough for now.    
144     const int COMPRESSED_AGENT_SIZE=30;
145     
146     char comp_agent[COMPRESSED_AGENT_SIZE];
147
148     // was bzero before, but unable to find bzero on solaris
149     for ( int i = 0; i < COMPRESSED_AGENT_SIZE; i++ ) {
150         comp_agent[i] = 0;
151     }
152
153     ostrstream str_buf( comp_agent,COMPRESSED_AGENT_SIZE);
154     handler *x = (base_ptr->get_obj_dict()).get_handler(
155       form("%s.%s", base_name, "sgml.dict"));
156     x->its_oid().asciiOut(str_buf);
157     
158
159     while(cursor.next(STRING_CODE, &bookLocator,
160                       STRING_CODE, &nodeLocator,
161                       STRING_CODE, &filename,
162                       INTEGER_CODE, &line_num,
163                       SKIP_CODE, /* TOC num */
164                       STRING_CODE, &title,
165                       STRING_CODE, &stitle,
166                       STRING_CODE, &style,
167                       NULL)){
168
169
170       CC_String *key = new CC_String(nodeLocator);
171
172       // check for duplicate node locator 
173       BTCollectable *val = node_dict.findValue( key );
174       if ( val ) {
175         delete key;
176         dupID++;
177         
178         cerr << "(ERROR) Duplicate section ID    = " << nodeLocator << endl
179              << "               found in file    = " << filename << endl
180              << "                     at line    = " << line_num << endl
181              << "         is in conflict with    " << endl
182              << "                  section ID    = " << nodeLocator << endl
183              << "                     in file    = " << val->filename() << endl
184              << "                     at line    = " << val->linenum() << "\n\n";
185
186
187       }
188       else {
189         
190         BTCollectable *val = new BTCollectable( filename, 
191                                                 line_num,
192                                                 bookLocator);
193         node_dict.insertKeyAndValue( key, val );
194
195       }
196
197       stylesheet_smart_ptr sheet(base_ptr, style);
198       char oid_buf[BUFSIZE];
199       ostrstream strout(oid_buf,BUFSIZE,ios::out);
200       sheet.its_oid().asciiOut(strout);
201       oid_buf[strout.pcount()] = NULL;
202
203       ncf->insert(STRING_CODE, nodeLocator,
204                   STRING_CODE, title,
205                   STRING_CODE, stitle,
206                   COMPRESSED_STRING_CODE, comp_agent, "",
207                   STRING_CODE, bookLocator,
208                   OID_CODE, "0.0", /* pointer to Book/CCF/DOC object */
209                   OID_CODE, oid_buf,
210                   NULL);
211     }
212
213   }
214   else {
215     
216     while(cursor.next(STRING_CODE, &bookLocator,
217                       STRING_CODE, &nodeLocator,
218                       STRING_CODE, &filename,
219                       INTEGER_CODE, &line_num,
220                       SKIP_CODE, /* TOC num */
221                       STRING_CODE, &title,
222                       STRING_CODE, &stitle,
223                       STRING_CODE, &style,
224                       NULL)){
225
226       CC_String *key = new CC_String(nodeLocator);
227
228       // check for duplicate node locator 
229       BTCollectable *val = node_dict.findValue( key );
230       if ( val ) {
231         delete key;
232         dupID++;
233
234         
235         cerr << "(ERROR) Duplicate section ID    = " << nodeLocator << endl
236              << "               found in file    = " << filename << endl
237              << "                     at line    = " << line_num << endl
238              << "         is in conflict with    " << endl
239              << "                  section ID    = " << nodeLocator << endl
240              << "                     in file    = " << val->filename() << endl
241              << "                     at line    = " << val->linenum() << "\n\n";
242
243       }
244       else {
245         
246         BTCollectable *val = new BTCollectable( filename, 
247                                                 line_num, 
248                                                 bookLocator );
249         node_dict.insertKeyAndValue( key , val );
250
251       }
252       
253       
254       stylesheet_smart_ptr sheet(base_ptr, style);
255       char oid_buf[BUFSIZE];
256       ostrstream strout(oid_buf,BUFSIZE,ios::out);
257       sheet.its_oid().asciiOut(strout);
258       oid_buf[strout.pcount()] = NULL;
259       
260       ncf->insert(STRING_CODE, nodeLocator,
261                   STRING_CODE, title,
262                   STRING_CODE, stitle,
263                   STRING_CODE, "",
264                   STRING_CODE, bookLocator,
265                   OID_CODE, "0.0", /* pointer to Book/CCF/DOC object */
266                   OID_CODE, oid_buf,
267                   NULL);
268     }
269     
270   }
271
272   if ( dupID ) {
273     throw(Unexpected(
274       form("Number of duplicated section ID found = %d", dupID)
275       ));
276   }
277
278   delete ncf;
279   node_dict.clearAndDestroy();
280 }
281
282 //-------------------------------------------------------------------------
283 static void
284 usage(const char *progname)
285 {
286   fprintf(stderr, "usage: %s [-compressed] [-load-style] <bookcasename> <bookcasedir>\n", progname);
287   exit(1);
288 }
289
290 //-------------------------------------------------------------------------
291 main(int argc, char **argv)
292 {
293   INIT_EXCEPTIONS();
294
295   set_new_handler( FreeStoreException );
296   
297   int ret = 1;
298   const char *progname = argv[0];
299   int compressed = 0;
300   int load_style_only = 0;
301
302 #ifdef FISH_DEBUG
303   DBUG_PROCESS(argv[0]);
304   if(getenv("FISH_DBUG")) DBUG_PUSH(getenv("FISH_DBUG"));
305 #endif
306   
307   argv++;
308   argc--;
309   
310   while(argc > 0 && argv[0][0] == '-'){
311     const char *opt = argv[0];
312     argv++;
313     argc--;
314     
315     if(strcmp(opt, "-compressed") == 0){
316       compressed = 1;
317     }
318     else if ( strcmp(opt, "-load-style") == 0 ) {
319       load_style_only = 1;
320     }
321     else {
322       usage(progname);
323     }
324   }
325   
326   if(argc == 2){
327     const char *base_name = argv[0];
328     const char *bookcaseDir = argv[1];
329
330     try{
331       BookCaseDB db(bookcaseDir);
332
333       if ( load_style_only ) {
334         writeStyleSheets(db);
335       }
336       else {
337         buildNCF(db, base_name, compressed);
338       }
339       ret = 0;
340     }
341
342     catch(PosixError&, pe){
343       fprintf(stderr, "%s: error on %s: %s\n",
344               progname, bookcaseDir, pe.msg());
345     }
346
347     catch(Unexpected&, pe) {
348       fprintf(stderr, "(ERROR) %s\n\n", pe.msg() );
349     }
350     
351     catch(mmdbException&, e) {
352       cerr << e;
353     }
354     
355     catch_any() {
356       fprintf(stderr, "*** Internal Error ***: unexpected exception\n");
357       abort();
358     }end_try;
359
360   }else{
361     usage(progname);
362   }
363
364   return ret;
365 }
366