fixed bug caused by nxmibc refactoring
[public/netxms.git] / src / snmp / nxmibc / nxmibc.cpp
CommitLineData
5039dede
AK
1/*
2** NetXMS - Network Management System
3** NetXMS MIB compiler
6308c9be 4** Copyright (C) 2005-2012 Victor Kirhenshtein
5039dede
AK
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19**
88227d9c 20** File: nxmibc.cpp
5039dede
AK
21**
22**/
23
24#include "nxmibc.h"
25
88227d9c
VK
26#ifdef _WIN32
27#include <conio.h>
28#endif
29
3a82d5ae
VK
30/**
31 * Severity codes
32 */
5039dede
AK
33#define MIBC_INFO 0
34#define MIBC_WARNING 1
35#define MIBC_ERROR 2
36
3a82d5ae
VK
37/**
38 * Externals
39 */
1a459ba3 40int ParseMIBFiles(StringList *fileList, SNMP_MIBObject **ppRoot);
5039dede 41
3a82d5ae
VK
42/**
43 * Static data
44 */
5039dede 45static char m_szOutFile[MAX_PATH] = "netxms.mib";
1a459ba3 46static StringList s_fileList;
88227d9c 47static bool s_pauseBeforeExit = false;
5039dede 48
300bec18
VK
49/**
50 * Errors
51 */
5039dede
AK
52static struct
53{
54 int nSeverity;
300bec18 55 const TCHAR *pszText;
5039dede
AK
56} m_errorList[] =
57{
300bec18
VK
58 { MIBC_INFO, _T("Operation completed successfully") },
59 { MIBC_ERROR, _T("Import symbol \"%hs\" unresolved") },
60 { MIBC_ERROR, _T("Import module \"%hs\" unresolved") },
61 { MIBC_ERROR, _T("Parser error - %hs in line %d") },
62 { MIBC_ERROR, _T("Cannot open input file (%hs)") },
63 { MIBC_ERROR, _T("Cannot resolve symbol %hs") },
64 { MIBC_WARNING, _T("Cannot resolve data type \"%hs\" for object \"%hs\"") }
5039dede
AK
65};
66
300bec18
VK
67/**
68 * Pause if needed
69 */
88227d9c
VK
70static void Pause()
71{
72 if (s_pauseBeforeExit)
73 {
74#ifdef _WIN32
300bec18 75 _tprintf(_T("Press any key to continue...\n"));
88227d9c
VK
76 _getch();
77#else
300bec18 78 _tprintf(_T("Press ENTER to continue...\n"));
88227d9c
VK
79 char temp[256];
80 fgets(temp, 255, stdin);
81#endif
82 }
83}
84
300bec18
VK
85/**
86 * Display error text and abort compilation
87 */
5039dede
AK
88extern "C" void Error(int nError, char *pszModule, ...)
89{
90 va_list args;
300bec18 91 static const TCHAR *severityText[] = { _T("INFO"), _T("WARNING"), _T("ERROR") };
5039dede 92
300bec18 93 _tprintf(_T("%hs: %s %03d: "), pszModule, severityText[m_errorList[nError].nSeverity], nError);
5039dede 94 va_start(args, pszModule);
300bec18 95 _vtprintf(m_errorList[nError].pszText, args);
5039dede 96 va_end(args);
300bec18 97 _tprintf(_T("\n"));
5039dede 98 if (m_errorList[nError].nSeverity == MIBC_ERROR)
88227d9c
VK
99 {
100 Pause();
5039dede 101 exit(1);
88227d9c 102 }
5039dede
AK
103}
104
300bec18
VK
105/**
106 * Display help and exit
107 */
108static void Help()
5039dede 109{
300bec18
VK
110 _tprintf(_T("Usage:\n\n")
111 _T("nxmibc [options] source1 ... sourceN\n\n")
112 _T("Valid options:\n")
113 _T(" -d <dir> : Include all MIB files from given directory to compilation\n")
6234a69f
EJ
114 _T(" -r : Scan sub-directories \n")
115 _T(" -e <ext> : Specify file extensions (default extension: \"txt\") \n")
300bec18
VK
116 _T(" -o <file> : Set output file name (default is netxms.mib)\n")
117 _T(" -P : Pause before exit\n")
118 _T(" -s : Strip descriptions from MIB objects\n")
119 _T(" -z : Compress output file\n")
120 _T("\n"));
88227d9c 121 exit(0);
5039dede
AK
122}
123
300bec18 124/**
300bec18
VK
125 * Scan directory for MIB files
126 */
1a459ba3 127static void ScanDirectory(const TCHAR *path, const StringSet *extensions, bool recursive)
5039dede 128{
1a459ba3 129 _TDIR *pDir = _topendir(path);
5039dede
AK
130 if (pDir != NULL)
131 {
1a459ba3 132 while(true)
5039dede 133 {
1a459ba3 134 struct _tdirent *pFile = _treaddir(pDir);
5039dede
AK
135 if (pFile == NULL)
136 break;
1a459ba3 137 if (_tcscmp(pFile->d_name, _T(".")) && _tcscmp(pFile->d_name, _T("..")))
5039dede 138 {
1a459ba3
VK
139 TCHAR szBuffer[MAX_PATH];
140 _sntprintf(szBuffer, MAX_PATH, _T("%s") FS_PATH_SEPARATOR _T("%s"), path, pFile->d_name);
141 if (recursive && (pFile->d_type == DT_DIR))
142 {
6234a69f 143 ScanDirectory(szBuffer, extensions, recursive);
1a459ba3 144 }
6234a69f 145 else
5039dede 146 {
1a459ba3 147 TCHAR *extension = _tcsrchr(pFile->d_name, _T('.'));
aca878da
VK
148#ifdef _WIN32
149 _tcslwr(extension);
150#endif
1a459ba3
VK
151 if ((extension != NULL) && extensions->contains(extension + 1))
152 s_fileList.add(szBuffer);
5039dede
AK
153 }
154 }
155 }
1a459ba3 156 _tclosedir(pDir);
5039dede
AK
157 }
158}
159
300bec18
VK
160/**
161 * Entry point
162 */
5039dede
AK
163int main(int argc, char *argv[])
164{
6234a69f
EJ
165 bool recursive = false;
166 bool scanDir = false;
5039dede
AK
167 SNMP_MIBObject *pRoot;
168 DWORD dwFlags = 0, dwRet;
88227d9c 169 int i, ch, rc = 0;
5039dede 170
d37e7f10 171 InitNetXMSProcess(true);
fe8ea784 172
d37e7f10
VK
173 _tprintf(_T("NetXMS MIB Compiler Version ") NETXMS_VERSION_STRING _T(" (") NETXMS_BUILD_TAG _T(")\n")
174 _T("Copyright (c) 2005-2017 Raden Solutions\n\n"));
5039dede 175
1a459ba3
VK
176 StringList paths;
177 StringSet extensions;
178 extensions.add(_T("txt"));
179
5039dede
AK
180 // Parse command line
181 opterr = 1;
6234a69f 182 while((ch = getopt(argc, argv, "rd:ho:e:Psz")) != -1)
5039dede
AK
183 {
184 switch(ch)
185 {
6234a69f 186 case 'e':
aca878da
VK
187#ifdef _WIN32
188#ifdef UNICODE
189 extensions.addPreallocated(_wcslwr(WideStringFromMBStringSysLocale(optarg)));
190#else
191 extensions.add(strlwr(optarg));
192#endif
193#else
1a459ba3
VK
194#ifdef UNICODE
195 extensions.addPreallocated(WideStringFromMBStringSysLocale(optarg));
196#else
197 extensions.add(optarg);
198#endif
aca878da 199#endif
6234a69f 200 break;
5039dede
AK
201 case 'h': // Display help and exit
202 Help();
203 break;
204 case 'd':
1a459ba3 205#ifdef UNICODE
86ab8f94 206 paths.addPreallocated(WideStringFromMBStringSysLocale(optarg));
1a459ba3 207#else
86ab8f94 208 paths.add(optarg);
1a459ba3 209#endif
6234a69f 210 scanDir = true;
5039dede
AK
211 break;
212 case 'o':
b07c50cc
VK
213 strncpy(m_szOutFile, optarg, MAX_PATH);
214 m_szOutFile[MAX_PATH - 1] = 0;
5039dede 215 break;
88227d9c
VK
216 case 'P':
217 s_pauseBeforeExit = true;
218 break;
6234a69f
EJ
219 case 'r':
220 recursive = true;
221 break;
5039dede
AK
222 case 's':
223 dwFlags |= SMT_SKIP_DESCRIPTIONS;
224 break;
225 case 'z':
226 dwFlags |= SMT_COMPRESS_DATA;
227 break;
228 case '?':
229 return 255;
230 default:
231 break;
232 }
233 }
234
6234a69f
EJ
235 if (scanDir)
236 {
1a459ba3 237 for(int i = 0; i < paths.size(); i++)
6234a69f 238 {
1a459ba3 239 ScanDirectory(paths.get(i), &extensions, recursive);
6234a69f
EJ
240 }
241 }
242
5039dede 243 for(i = optind; i < argc; i++)
5039dede 244 {
1a459ba3
VK
245#ifdef UNICODE
246 s_fileList.addPreallocated(WideStringFromMBStringSysLocale(argv[i]));
247#else
248 s_fileList.add(argv[i]);
249#endif
250 }
251
252 if (s_fileList.size() > 0)
253 {
254 ParseMIBFiles(&s_fileList, &pRoot);
5039dede
AK
255
256 if (pRoot != NULL)
257 {
b07c50cc
VK
258#ifdef UNICODE
259 WCHAR *wname = WideStringFromMBString(m_szOutFile);
260 dwRet = SNMPSaveMIBTree(wname, pRoot, dwFlags);
261 free(wname);
262#else
5039dede 263 dwRet = SNMPSaveMIBTree(m_szOutFile, pRoot, dwFlags);
b07c50cc 264#endif
1f4eb5d3 265 delete pRoot;
5039dede 266 if (dwRet != SNMP_ERR_SUCCESS)
968f66ce 267 {
300bec18 268 _tprintf(_T("ERROR: Cannot save output file %hs (%s)\n"), m_szOutFile, SNMPGetErrorText(dwRet));
968f66ce
EJ
269 rc = 1;
270 }
5039dede
AK
271 }
272 }
273 else
274 {
300bec18 275 _tprintf(_T("ERROR: No source files given\n"));
88227d9c 276 rc = 1;
5039dede
AK
277 }
278
88227d9c
VK
279 Pause();
280 return rc;
5039dede 281}