1 //
2 // $Id: sphinxutils.h 4113 2013-08-26 07:43:28Z deogar $
3 //
4 
5 //
6 // Copyright (c) 2001-2013, Andrew Aksyonoff
7 // Copyright (c) 2008-2013, Sphinx Technologies Inc
8 // All rights reserved
9 //
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License. You should have
12 // received a copy of the GPL license along with this program; if you
13 // did not, you can find it at http://www.gnu.org/
14 //
15 
16 /// @file sphinxutils.h
17 /// Declarations for the stuff shared by all Sphinx utilities.
18 
19 #ifndef _sphinxutils_
20 #define _sphinxutils_
21 
22 #include <ctype.h>
23 #include <stdarg.h>
24 
25 /////////////////////////////////////////////////////////////////////////////
26 
27 /// my own isalpha (let's build our own theme park!)
sphIsAlpha(int c)28 inline int sphIsAlpha ( int c )
29 {
30 	return ( c>='0' && c<='9' ) || ( c>='a' && c<='z' ) || ( c>='A' && c<='Z' ) || c=='-' || c=='_';
31 }
32 
33 
34 /// my own isspace
sphIsSpace(int iCode)35 inline bool sphIsSpace ( int iCode )
36 {
37 	return iCode==' ' || iCode=='\t' || iCode=='\n' || iCode=='\r';
38 }
39 
40 
41 /// check for keyword modifiers
sphIsModifier(int iSymbol)42 inline bool sphIsModifier ( int iSymbol )
43 {
44 	return iSymbol=='^' || iSymbol=='$' || iSymbol=='=' || iSymbol=='*';
45 }
46 
47 
48 /// string splitter, extracts sequences of alphas (as in sphIsAlpha)
sphSplit(CSphVector<CSphString> & dOut,const char * sIn)49 inline void sphSplit ( CSphVector<CSphString> & dOut, const char * sIn )
50 {
51 	if ( !sIn )
52 		return;
53 
54 	const char * p = (char*)sIn;
55 	while ( *p )
56 	{
57 		// skip non-alphas
58 		while ( (*p) && !sphIsAlpha(*p) )
59 			p++;
60 		if ( !(*p) )
61 			break;
62 
63 		// this is my next token
64 		assert ( sphIsAlpha(*p) );
65 		const char * sNext = p;
66 		while ( sphIsAlpha(*p) )
67 			p++;
68 		if ( sNext!=p )
69 			dOut.Add().SetBinary ( sNext, p-sNext );
70 	}
71 }
72 
73 
74 /// config section (hash of variant values)
75 class CSphConfigSection : public SmallStringHash_T < CSphVariant >
76 {
77 public:
78 	/// get integer option value by key and default value
79 	int GetInt ( const char * sKey, int iDefault=0 ) const
80 	{
81 		CSphVariant * pEntry = (*this)( sKey );
82 		return pEntry ? pEntry->intval() : iDefault;
83 	}
84 
85 	/// get float option value by key and default value
86 	float GetFloat ( const char * sKey, float fDefault=0.0f ) const
87 	{
88 		CSphVariant * pEntry = (*this)( sKey );
89 		return pEntry ? pEntry->floatval() : fDefault;
90 	}
91 
92 	/// get string option value by key and default value
93 	const char * GetStr ( const char * sKey, const char * sDefault="" ) const
94 	{
95 		CSphVariant * pEntry = (*this)( sKey );
96 		return pEntry ? pEntry->cstr() : sDefault;
97 	}
98 
99 	/// get size option (plain int, or with K/M prefix) value by key and default value
100 	int GetSize ( const char * sKey, int iDefault ) const;
101 };
102 
103 /// config section type (hash of sections)
104 typedef SmallStringHash_T < CSphConfigSection >	CSphConfigType;
105 
106 /// config (hash of section types)
107 typedef SmallStringHash_T < CSphConfigType >	CSphConfig;
108 
109 /// simple config file
110 class CSphConfigParser
111 {
112 public:
113 	CSphConfig		m_tConf;
114 
115 public:
116 					CSphConfigParser ();
117 	bool			Parse ( const char * sFileName, const char * pBuffer = NULL );
118 
119 	// fail-save loading new config over existing.
120 	bool			ReParse ( const char * sFileName, const char * pBuffer = NULL );
121 
122 protected:
123 	CSphString		m_sFileName;
124 	int				m_iLine;
125 	CSphString		m_sSectionType;
126 	CSphString		m_sSectionName;
127 	char			m_sError [ 1024 ];
128 
129 	int					m_iWarnings;
130 	static const int	WARNS_THRESH	= 5;
131 
132 protected:
133 	bool			IsPlainSection ( const char * sKey );
134 	bool			IsNamedSection ( const char * sKey );
135 	bool			AddSection ( const char * sType, const char * sSection );
136 	void			AddKey ( const char * sKey, char * sValue );
137 	bool			ValidateKey ( const char * sKey );
138 
139 #if !USE_WINDOWS
140 	bool			TryToExec ( char * pBuffer, const char * szFilename, CSphVector<char> & dResult );
141 #endif
142 	char *			GetBufferString ( char * szDest, int iMax, const char * & szSource );
143 };
144 
145 #if !USE_WINDOWS
146 bool TryToExec ( char * pBuffer, const char * szFilename, CSphVector<char> & dResult, char * sError, int iErrorLen );
147 #endif
148 
149 /////////////////////////////////////////////////////////////////////////////
150 
151 enum
152 {
153 	TOKENIZER_SBCS		= 1,
154 	TOKENIZER_UTF8		= 2,
155 	TOKENIZER_NGRAM	= 3
156 };
157 
158 /// load config file
159 const char *	sphLoadConfig ( const char * sOptConfig, bool bQuiet, CSphConfigParser & cp );
160 
161 /// configure tokenizer from index definition section
162 bool			sphConfTokenizer ( const CSphConfigSection & hIndex, CSphTokenizerSettings & tSettings, CSphString & sError );
163 
164 /// configure dictionary from index definition section
165 void			sphConfDictionary ( const CSphConfigSection & hIndex, CSphDictSettings & tSettings );
166 
167 /// configure index from index definition section
168 bool			sphConfIndex ( const CSphConfigSection & hIndex, CSphIndexSettings & tSettings, CSphString & sError );
169 
170 /// try to set dictionary, tokenizer and misc settings for an index (if not already set)
171 bool			sphFixupIndexSettings ( CSphIndex * pIndex, const CSphConfigSection & hIndex, CSphString & sError );
172 
173 enum ESphLogLevel
174 {
175 	SPH_LOG_FATAL	= 0,
176 	SPH_LOG_WARNING	= 1,
177 	SPH_LOG_INFO	= 2,
178 	SPH_LOG_DEBUG	= 3,
179 	SPH_LOG_VERBOSE_DEBUG = 4,
180 	SPH_LOG_VERY_VERBOSE_DEBUG = 5
181 };
182 
183 typedef void ( *SphLogger_fn )( ESphLogLevel, const char *, va_list );
184 
185 void sphWarning ( const char * sFmt, ... ) __attribute__((format(printf,1,2)));
186 void sphInfo ( const char * sFmt, ... ) __attribute__((format(printf,1,2)));
187 void sphLogFatal ( const char * sFmt, ... ) __attribute__((format(printf,1,2)));
188 void sphLogDebug ( const char * sFmt, ... ) __attribute__((format(printf,1,2)));
189 void sphLogDebugv ( const char * sFmt, ... ) __attribute__((format(printf,1,2)));
190 void sphLogDebugvv ( const char * sFmt, ... ) __attribute__((format(printf,1,2)));
191 void sphSetLogger ( SphLogger_fn fnLog );
192 
193 //////////////////////////////////////////////////////////////////////////
194 
195 /// how do we properly exit from the crash handler?
196 #if !USE_WINDOWS
197 	#ifndef NDEBUG
198 		// UNIX debug build, die and dump core
199 		#define CRASH_EXIT { signal ( sig, SIG_DFL ); kill ( getpid(), sig ); }
200 	#else
201 		// UNIX release build, just die
202 		#define CRASH_EXIT exit ( 2 )
203 	#endif
204 #else
205 	#ifndef NDEBUG
206 		// Windows debug build, show prompt to attach debugger
207 		#define CRASH_EXIT return EXCEPTION_CONTINUE_SEARCH
208 	#else
209 		// Windows release build, just die
210 		#define CRASH_EXIT return EXCEPTION_EXECUTE_HANDLER
211 	#endif
212 #endif
213 
214 /// simple write wrapper
215 /// simplifies partial write checks, and also supresses "fortified" glibc warnings
216 bool sphWrite ( int iFD, const void * pBuf, size_t iSize );
217 
218 /// async safe, BUT NOT THREAD SAFE, fprintf
219 void sphSafeInfo ( int iFD, const char * sFmt, ... );
220 
221 #if !USE_WINDOWS
222 /// UNIX backtrace gets printed out to a stream
223 void sphBacktrace ( int iFD, bool bSafe=false );
224 #else
225 /// Windows minidump gets saved to a file
226 void sphBacktrace ( EXCEPTION_POINTERS * pExc, const char * sFile );
227 #endif
228 
229 #endif // _sphinxutils_
230 
231 //
232 // $Id: sphinxutils.h 4113 2013-08-26 07:43:28Z deogar $
233 //
234