libcsdbg  1.28
C++ exception (and generic) stack trace debug library
dictionary & csdbg::dictionary::load_file ( const i8 path)
virtual

Load words from a dictionary file.

Parameters
[in]paththe path of the data file
Returns
*this
Exceptions
std::bad_alloc
csdbg::exception
Note
Each non-empty line in the file is translated as a single token. A line with only whitespace characters is considered an empty line. The tokens are trimmed to remove leading and trailing whitespace characters. If the file is empty no tokens are loaded, but the object remains valid
Attention
The file is memory mapped

Definition at line 193 of file dictionary.cpp.

References __D_ASSERT, csdbg::chain< string >::add(), csdbg::util::dbg_info(), csdbg::util::dbg_warn(), csdbg::util::is_readable(), csdbg::util::is_regular(), csdbg::string::length(), likely, m_name, csdbg::string::trim(), and unlikely.

Referenced by dictionary().

194 {
195  __D_ASSERT(path != NULL);
196  if ( unlikely(path == NULL) )
197  return *this;
198 
199  /* Stat the dictionary file path and make some preliminary checks */
200  fileinfo_t inf;
201  i32 retval = stat(path, &inf);
202  if ( unlikely(errno == ENOENT) )
203  throw exception("file '%s' does not exist", path);
204 
205  else if ( unlikely(retval < 0) )
206  throw exception(
207  "failed to stat path '%s' (errno %d - %s)",
208  path,
209  errno,
210  strerror(errno)
211  );
212 
213  else if ( unlikely(!util::is_regular(inf)) )
214  throw exception("'%s' is not a regular file", path);
215 
216  else if ( unlikely(!util::is_readable(inf)) )
217  throw exception("file '%s' is not readable", path);
218 
219  i32 sz = inf.st_size;
220  if ( unlikely(sz == 0) ) {
221  util::dbg_warn("dictionary file '%s' is empty", path);
222  return *this;
223  }
224 
225  /* Open the file */
226  i32 fd;
227  do {
228  fd = open(path, O_RDONLY);
229  }
230  while ( unlikely(fd < 0 && errno == EINTR) );
231 
232  if ( unlikely(fd < 0) )
233  throw exception(
234  "failed to open file '%s' (errno %d - %s)",
235  path,
236  errno,
237  strerror(errno)
238  );
239 
240  /* Memory map the file */
241  void *mmap_base = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
242  if ( unlikely(mmap_base == MAP_FAILED) ) {
243  close(fd);
244  throw exception(
245  "failed to memory map file '%s' (errno %d - %s)",
246  path,
247  errno,
248  strerror(errno)
249  );
250  }
251 
252  string *word = NULL;
253  i32 cnt = 0;
254 
255  /* If an exception occurs, unmap/close the file, clean up and rethrow it */
256  try {
257  i32 bytes = sz;
258  i8 *offset, *cur;
259  offset = cur = static_cast<i8*> (mmap_base);
260 
261  /* Load the dictionary words */
262  while ( likely(bytes-- > 0) )
263  if ( unlikely(*cur == '\n') ) {
264  if ( likely(cur != offset) ) {
265  word = new string("%.*s", cur - offset, offset);
266  word->trim();
267 
268  if ( unlikely(word->length() == 0) )
269  delete word;
270 
271  else {
272  cnt++;
273  add(word);
274  }
275 
276  word = NULL;
277  }
278 
279  offset = ++cur;
280  }
281  else
282  ++cur;
283  }
284 
285  catch (...) {
286  delete word;
287  munmap(mmap_base, sz);
288  close(fd);
289  throw;
290  }
291 
292  munmap(mmap_base, sz);
293  close(fd);
294 
295 #if CSDBG_DBG_LEVEL & CSDBG_DBGL_INFO
296  if ( likely(cnt > 0) )
298  "file '%s' (%d word%s) loaded on dictionary %s",
299  path,
300  cnt,
301  (cnt != 1) ? "s" : "",
302  m_name
303  );
304 
305  else
306  util::dbg_info("dictionary file '%s' is empty", path);
307 #endif
308 
309  return *this;
310 }
char i8
8-bit signed integer
Definition: config.hpp:72
struct stat fileinfo_t
File metadata.
Definition: config.hpp:112
#define likely(expr)
Offer a hint (positive) to the pipeline branch predictor.
Definition: config.hpp:344
static void dbg_warn(const i8 *,...)
Print a warning debug message on the standard error stream.
Definition: util.cpp:703
i8 * m_name
Dictionary name.
Definition: dictionary.hpp:38
static bool is_readable(const fileinfo_t &)
Check if the process has read access to a file.
Definition: util.cpp:445
virtual chain & add(string *)
int i32
32-bit signed integer
Definition: config.hpp:82
static bool is_regular(const fileinfo_t &)
Check if a file is a regular one.
Definition: util.cpp:419
#define unlikely(expr)
Offer a hint (negative) to the pipeline branch predictor.
Definition: config.hpp:349
static void dbg_info(const i8 *,...)
Print an informational debug message on the standard error stream.
Definition: util.cpp:680
#define __D_ASSERT(x)
Assertion macro.
Definition: config.hpp:268

+ Here is the call graph for this function:

+ Here is the caller graph for this function: