Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / nsgmls / EntityApp.C
1 /* $XConsortium: EntityApp.C /main/1 1996/07/29 16:49:57 cde-hp $ */
2 // Copyright (c) 1996 James Clark
3 // See the file COPYING for copying permission.
4
5 #ifdef __GNUG__
6 #pragma implementation
7 #endif
8
9 #include "splib.h"
10 #include "EntityApp.h"
11 #include "sptchar.h"
12
13 #include <stdlib.h>
14
15 #ifdef SP_MULTI_BYTE
16 #include "ISO8859InputCodingSystem.h"
17 #endif
18
19 #include "PosixStorage.h"
20 #include "URLStorage.h"
21 #include "LiteralStorage.h"
22 #include "ExtendEntityManager.h"
23 #include "SOEntityCatalog.h"
24 #include "CodingSystem.h"
25 #include "macros.h"
26
27 #ifndef SGML_SEARCH_PATH_DEFAULT
28 #define SGML_SEARCH_PATH_DEFAULT SP_T("")
29 #endif
30
31 #ifndef SGML_CATALOG_FILES_DEFAULT
32 #define SGML_CATALOG_FILES_DEFAULT SP_T("")
33 #endif /* not SGML_CATALOG_FILES_DEFAULT */
34
35 #ifdef SP_NAMESPACE
36 namespace SP_NAMESPACE {
37 #endif
38
39 #ifdef MSDOS_FILENAMES
40 const Char FILE_SEP = ';';
41 #else
42 const Char FILE_SEP = ':';
43 #endif
44
45 #ifdef SP_MULTI_BYTE
46 static ISO8859InputCodingSystem iso8859_2InputCodingSystem(2);
47 static ISO8859InputCodingSystem iso8859_3InputCodingSystem(3);
48 static ISO8859InputCodingSystem iso8859_4InputCodingSystem(4);
49 static ISO8859InputCodingSystem iso8859_5InputCodingSystem(5);
50 static ISO8859InputCodingSystem iso8859_6InputCodingSystem(6);
51 static ISO8859InputCodingSystem iso8859_7InputCodingSystem(7);
52 static ISO8859InputCodingSystem iso8859_8InputCodingSystem(8);
53 static ISO8859InputCodingSystem iso8859_9InputCodingSystem(9);
54
55 static struct {
56   const char *name;
57   const InputCodingSystem *cs;
58 } inputCodingSystems[] = {
59  { "IS8859-2", &iso8859_2InputCodingSystem },
60  { "IS8859-3", &iso8859_3InputCodingSystem },
61  { "IS8859-4", &iso8859_4InputCodingSystem },
62  { "IS8859-5", &iso8859_5InputCodingSystem },
63  { "IS8859-6", &iso8859_6InputCodingSystem },
64  { "IS8859-7", &iso8859_7InputCodingSystem },
65  { "IS8859-8", &iso8859_8InputCodingSystem },
66  { "IS8859-9", &iso8859_9InputCodingSystem },
67 };
68
69 #endif /* SP_MULTI_BYTE */
70
71 #ifdef SP_MULTI_BYTE
72 static UnivCharsetDesc::Range range = { 0, 65536, 0 };
73 #else
74 static UnivCharsetDesc::Range range = { 0, 256, 0 };
75 #endif
76
77 EntityApp::EntityApp()
78 : mapCatalogDocument_(0),
79   systemCharset_(UnivCharsetDesc(&range, 1))
80 {
81   registerOption('c', SP_T("catalog_sysid"));
82   registerOption('C');
83   registerOption('D', SP_T("dir"));
84 }
85
86 void EntityApp::processOption(AppChar opt, const AppChar *arg)
87 {
88   switch (opt) {
89   case 'c':
90     catalogSysids_.push_back(arg);
91     break;
92   case 'C':
93     mapCatalogDocument_ = 1;
94     break;
95   case 'D':
96     searchDirs_.push_back(arg);
97     break;
98   default:
99     CmdLineApp::processOption(opt, arg);
100     break;
101   }
102 }
103
104 int EntityApp::processArguments(int argc, AppChar **argv)
105 {
106   StringC sysid;
107   if (!makeSystemId(argc, argv, sysid))
108     return 1;
109   return processSysid(sysid);
110 }
111
112 Boolean EntityApp::makeSystemId(int nFiles, AppChar *const *files,
113                                         StringC &result)
114 {
115   Vector<StringC> filenames(nFiles == 0 ? 1 : nFiles);
116   int i;
117   for (i = 0; i < nFiles; i++)
118     filenames[i] = convertInput(tcscmp(files[i], SP_T("-")) == 0
119                                 ? SP_T("<OSFD>0")
120                                 : files[i]);
121   if (nFiles == 0)
122     filenames[0] = convertInput(SP_T("<OSFD>0"));
123   return entityManager()->mergeSystemIds(filenames,
124                                          mapCatalogDocument_,
125                                          systemCharset_,
126                                          *this,
127                                          result);
128 }
129
130
131 Ptr<ExtendEntityManager> &EntityApp::entityManager()
132 {
133   if (!entityManager_.isNull())
134     return entityManager_;
135   PosixStorageManager *sm
136     = new PosixStorageManager("OSFILE",
137                               systemCharset_.desc(),
138 #ifndef SP_WIDE_SYSTEM
139                               codingSystem(),
140 #endif
141                               5);
142   size_t i;
143   for (i = 0; i < searchDirs_.size(); i++)
144     sm->addSearchDir(convertInput(searchDirs_[i]));
145   {
146     const AppChar *e = tgetenv(SP_T("SGML_SEARCH_PATH"));
147     if (!e)
148       e = SGML_SEARCH_PATH_DEFAULT;
149     if (*e) {
150       StringC str(convertInput(e));
151       size_t i = 0;
152       size_t start = 0;
153       for (;;) {
154         if (i == str.size() || str[i] == FILE_SEP) {
155           sm->addSearchDir(StringC(str.data() + start,
156                                    i - start));
157           if (i == str.size())
158             break;
159           start = ++i;
160         }
161         else
162           i++;
163       }
164     }
165   }
166
167   entityManager_ = ExtendEntityManager::make(sm, codingSystem());
168   entityManager_
169   ->registerStorageManager(new PosixFdStorageManager("OSFD",
170                                                      systemCharset_.desc()));
171   entityManager_->registerStorageManager(new URLStorageManager("URL"));
172   entityManager_->registerStorageManager(new LiteralStorageManager("LITERAL"));
173   for (i = 0;; i++) {
174     const char *s;
175     const CodingSystem *p = codingSystem(i, s);
176     if (!p)
177       break;
178     entityManager_->registerCodingSystem(s, p);
179   }
180 #ifdef SP_MULTI_BYTE
181   for (i = 0; i < SIZEOF(inputCodingSystems); i++)
182     entityManager_->registerCodingSystem(inputCodingSystems[i].name,
183                                          inputCodingSystems[i].cs);
184 #endif
185   Vector<StringC> v;
186   for (i = 0; i < catalogSysids_.size(); i++)
187     // filenames specified on command-line must exist
188     v.push_back(convertInput(catalogSysids_[i]));
189   {
190     const AppChar *e = tgetenv(SP_T("SGML_CATALOG_FILES"));
191     if (!e)
192       e = SGML_CATALOG_FILES_DEFAULT;
193     if (*e) {
194       StringC str(convertInput(e));
195       size_t i = 0;
196       size_t start = 0;
197       for (;;) {
198         if (i == str.size() || str[i] == FILE_SEP) {
199           v.push_back(StringC(str.data() + start,
200                               i - start));
201           if (i == str.size())
202             break;
203           start = ++i;
204         }
205         else
206           i++;
207       }
208     }
209   }
210   entityManager_->setCatalogManager(SOCatalogManager::make(v,
211                                                            catalogSysids_.size(),
212                                                            systemCharset_,
213                                                            systemCharset_));
214   return entityManager_;
215 }
216
217
218 #ifdef SP_NAMESPACE
219 }
220 #endif