feisty meow concerns codebase  2.140
version_ini.cpp
Go to the documentation of this file.
1 /*****************************************************************************\
2 * *
3 * Name : version_ini editing support *
4 * Author : Chris Koeritz *
5 * *
6 *******************************************************************************
7 * Copyright (c) 1995-$now By Author. This program is free software; you can *
8 * redistribute it and/or modify it under the terms of the GNU General Public *
9 * License as published by the Free Software Foundation; either version 2 of *
10 * the License or (at your option) any later version. This is online at: *
11 * http://www.fsf.org/copyleft/gpl.html *
12 * Please send any updates to: fred@gruntose.com *
13 \*****************************************************************************/
14 
15 #include "version_ini.h"
16 
17 #include <basis/functions.h>
20 #include <filesystem/byte_filer.h>
21 #include <filesystem/directory.h>
22 #include <filesystem/filename.h>
26 
27 #include <sys/stat.h>
28 #ifdef __WIN32__
29  #include <io.h>
30 #endif
31 
32 using namespace basis;
33 using namespace configuration;
34 using namespace filesystem;
35 using namespace loggers;
36 using namespace structures;
37 
38 namespace versions {
39 
40 // the following are all strings that are sought in the version.ini file.
41 const char *version_ini::VERSION_SECTION = "version";
42  // the section that version entries are stored under in the INI file.
43 const char *version_ini::COMPANY_KEY="company";
44 const char *version_ini::COPYRIGHT_KEY="copyright";
45 const char *version_ini::LEGAL_INFO_KEY="legal_info";
46 const char *version_ini::PRODUCT_KEY="product_name";
47 const char *version_ini::WEB_SITE_KEY="web_site";
48 
49 // not used anymore; now matched with the file version's first two digits.
50 //const version PRODUCT_VERSION(2, 0, 0, 0);
51  // the current version of the entire product.
52 
53 // these are field names in the INI file.
54 const char *version_ini::MAJOR = "major";
55 const char *version_ini::MINOR = "minor";
56 const char *version_ini::REVISION = "revision";
57 const char *version_ini::BUILD = "build";
58 const char *version_ini::DESCRIPTION = "description";
59 const char *version_ini::ROOT = "root";
60 const char *version_ini::NAME = "name";
61 const char *version_ini::EXTENSION = "extension";
62 const char *version_ini::OLE_AUTO = "ole_auto";
63 
64 // this is the default version INI file name, if no other is specified.
65 const char *VERSION_INI_FILE = "/version.ini";
66 
67 #undef LOG
68 #define LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t)
69 
70 version_ini::version_ini(const astring &path_name)
71 : _loaded(false),
72  _path_name(new filename(path_name)),
73  _ini(new ini_configurator("", ini_configurator::RETURN_ONLY)),
74  _held_record(new version_record)
75 {
76  check_name(*_path_name);
77  _ini->name(*_path_name);
78 }
79 
81 {
82  WHACK(_ini);
83  WHACK(_path_name);
84  WHACK(_held_record);
85 }
86 
88 {
89  astring extension = _ini->load(VERSION_SECTION, OLE_AUTO, "");
90  return (extension.lower().t());
91 }
92 
94 {
95  astring extension = _ini->load(VERSION_SECTION, EXTENSION, "");
96  if (extension.lower() == astring("exe")) return true;
97  return false;
98 }
99 
100 bool version_ini::library() { return !executable(); }
101 
102 bool version_ini::writable() { return _path_name->is_writable(); }
103 
104 void version_ini::check_name(filename &to_examine)
105 {
106  // if it's just a directory name, add the file name.
107  if (to_examine.is_directory()) {
108  to_examine = astring(to_examine) + VERSION_INI_FILE;
109  to_examine.canonicalize();
110  }
111 
112  // add the directory explicitly (if it's not there already) or the ini
113  // writer will get it from the windows directory.
114  if ( (to_examine.raw()[0] != '.') && (to_examine.dirname().raw().equal_to(".")) ) {
115  to_examine = astring("./") + to_examine;
116  to_examine.canonicalize();
117  }
118 }
119 
120 bool version_ini::executable(const astring &path_name_in)
121 {
122  filename path_name(path_name_in);
123  check_name(path_name);
124  ini_configurator temp_ini(path_name, ini_configurator::RETURN_ONLY);
125  astring extension = temp_ini.load(VERSION_SECTION, EXTENSION, "");
126  extension.to_lower();
127  if (extension == astring("exe")) return true;
128  return false;
129 }
130 
131 bool version_ini::library(const astring &path_name)
132 { return !executable(path_name); }
133 
135 {
136  if (_loaded) return _held_record->file_version;
137  get_record();
138  return _held_record->file_version;
139 }
140 
141 void version_ini::set_version(const version &to_write, bool write_ini)
142 {
143  _held_record->file_version = to_write; // copy the version we're given.
144 
145  // set the product version appropriately to the file version.
146  _held_record->product_version = to_write;
147  _held_record->product_version.set_component(version::REVISION, "0");
148  _held_record->product_version.set_component(version::BUILD, "0");
149 
150  if (!write_ini) return; // they don't want a change to the file.
151  _ini->store(VERSION_SECTION, MAJOR, to_write.get_component(version::MAJOR));
152  _ini->store(VERSION_SECTION, MINOR, to_write.get_component(version::MINOR));
153  _ini->store(VERSION_SECTION, REVISION, to_write.get_component(version::REVISION));
154  _ini->store(VERSION_SECTION, BUILD, to_write.get_component(version::BUILD));
155 }
156 
158 {
160  parts += _ini->load(VERSION_SECTION, MAJOR, "0");
161  parts += _ini->load(VERSION_SECTION, MINOR, "0");
162  parts += _ini->load(VERSION_SECTION, REVISION, "0");
163  parts += _ini->load(VERSION_SECTION, BUILD, "0");
164  return version(parts);
165 }
166 
167 version_record &version_ini::access_record() { return *_held_record; }
168 
170 {
171  FUNCDEF("get_record");
172  if (_loaded) return *_held_record;
173  version_record to_return;
174  to_return.description = _ini->load(VERSION_SECTION, DESCRIPTION, "");
175  to_return.file_version = read_version_from_ini();
176  to_return.internal_name = _ini->load(VERSION_SECTION, NAME, "");
177  to_return.original_name = _ini->load(VERSION_SECTION, ROOT, "");
178  to_return.original_name += ".";
179 
180  // the dll type of extension is a hard default. anything besides the exe
181  // ending gets mapped to dll.
182  astring extension = _ini->load(VERSION_SECTION, EXTENSION, "");
183  extension.to_lower();
184  if (extension.equal_to("dll")) {}
185  else if (extension.equal_to("exe")) {}
186  else extension.equal_to("dll");
187  to_return.original_name += extension;
188 
189  to_return.product_version = to_return.file_version;
190  to_return.product_version.set_component(version::REVISION, "0");
191  to_return.product_version.set_component(version::BUILD, "0");
192 
193  to_return.product_name = _ini->load(VERSION_SECTION, PRODUCT_KEY, "");
194  to_return.company_name = _ini->load(VERSION_SECTION, COMPANY_KEY, "");
195  to_return.copyright = _ini->load(VERSION_SECTION, COPYRIGHT_KEY, "");
196  to_return.trademarks = _ini->load(VERSION_SECTION, LEGAL_INFO_KEY, "");
197  to_return.web_address = _ini->load(VERSION_SECTION, WEB_SITE_KEY, "");
198 
199  *_held_record = to_return;
200  _loaded = true;
201  return to_return;
202 }
203 
204 void version_ini::set_record(const version_record &to_write, bool write_ini)
205 {
206  *_held_record = to_write;
207  if (write_ini) {
208  _ini->store(VERSION_SECTION, DESCRIPTION, to_write.description);
209  set_version(to_write.file_version, write_ini);
210  _ini->store(VERSION_SECTION, ROOT, to_write.original_name);
211  _ini->store(VERSION_SECTION, NAME, to_write.internal_name);
212  }
213  _loaded = true; // we consider this to be the real version now.
214 }
215 
217 
219 #ifndef NO_VERSION\n\
220 #include <winver.h>\n\
221 #include <__build_version.h>\n\
222 #include <__build_configuration.h>\n\
223 #define BI_PLAT_WIN32\n\
224  // force 32 bit compile.\n\
225 1 VERSIONINFO LOADONCALL MOVEABLE\n\
226 FILEVERSION __build_FILE_VERSION_COMMAS\n\
227 PRODUCTVERSION __build_PRODUCT_VERSION_COMMAS\n\
228 FILEFLAGSMASK 0\n\
229 FILEFLAGS VS_FFI_FILEFLAGSMASK\n\
230 #if defined(BI_PLAT_WIN32)\n\
231  FILEOS VOS__WINDOWS32\n\
232 #else\n\
233  FILEOS VOS__WINDOWS16\n\
234 #endif\n\
235 FILETYPE VFT_APP\n\
236 BEGIN\n\
237  BLOCK \"StringFileInfo\"\n\
238  BEGIN\n\
239  // Language type = U.S. English(0x0409) and Character Set = Windows, Multilingual(0x04b0)\n\
240  BLOCK \"040904b0\" // Matches VarFileInfo Translation hex value.\n\
241  BEGIN\n\
242  VALUE \"CompanyName\", __build_company \"\\000\"\n\
243 #ifndef _DEBUG\n\
244  VALUE \"FileDescription\", \"$file_desc\\000\"\n\
245 #else\n\
246  VALUE \"FileDescription\", \"$file_desc (DEBUG)\\000\"\n\
247 #endif\n\
248  VALUE \"FileVersion\", __build_FILE_VERSION \"\\000\" \n\
249  VALUE \"ProductVersion\", __build_PRODUCT_VERSION \"\\000\" \n\
250  VALUE \"InternalName\", \"$internal\\000\"\n\
251  VALUE \"LegalCopyright\", __build_copyright \"\\000\"\n\
252  VALUE \"LegalTrademarks\", __build_legal_info \"\\000\"\n\
253  VALUE \"OriginalFilename\", \"$original_name\\000\"\n\
254  VALUE \"ProductName\", __build_product_name \"\\000\"\n\
255  $special_ole_flag\n\
256  END\n\
257  END\n\
258 \n\
259  BLOCK \"VarFileInfo\"\n\
260  BEGIN\n\
261  VALUE \"Translation\", 0x0409, 0x04b0 // US English (0x0409) and win32 multilingual (0x04b0)\n\
262  END\n\
263 END\n\
264 #endif\n";
265 
267 
268 // replaces every occurrence of the keyword in "tag" with the "replacement".
269 #define REPLACE(tag, replacement) \
270  new_version_entry.replace_all(tag, replacement); \
271 
272 bool version_ini::write_rc(const astring &header_store, const version_record &to_write)
273 {
274  FUNCDEF("write_rc");
275  astring new_version_entry(version_rc_template);
276 
277  // $file_ver -> w, x, y, z for version of the file.
278  REPLACE("$file_ver", to_write.file_version.flex_text_form(version::COMMAS));
279 
280  // $prod_ver -> w, x, y, z for version of the product.
281  REPLACE("$prod_ver", to_write.product_version.flex_text_form
282  (version::COMMAS));
283 
284  // $company -> name of company.
285  REPLACE("$company", to_write.company_name);
286 
287  // $file_desc -> description of file.
288  astring description_release = to_write.description;
289  REPLACE("$file_desc", description_release);
290  astring description_debug = to_write.description
291  + astring(" -- Debug Version");
292  REPLACE("$file_desc", description_debug);
293 
294  // $file_txt_ver -> file version in form w.x.y.z.
295  REPLACE("$file_txt_ver", to_write.file_version.flex_text_form(version::DOTS));
296 
297  // $internal -> internal name of the library, without extensions?
298  REPLACE("$internal", to_write.internal_name);
299 
300  // $copyright -> copyright held by us.
301  REPLACE("$copyright", to_write.copyright);
302 
303  // $legal_tm -> the legal trademarks that must be included, e.g. windows?
304  REPLACE("$legal_tm", to_write.trademarks);
305 
306  // $original_name -> the file's name before possible renamings.
307  REPLACE("$original_name", to_write.original_name);
308 
309  // $prod_name -> the name of the product that this belongs to.
310  REPLACE("$prod_name", to_write.product_name);
311 
312  // $prod_txt_ver -> product version in form w.x.y.z.
313  REPLACE("$prod_txt_ver", to_write.product_version
314  .flex_text_form(version::DOTS, version::MINOR));
315 
316  astring special_filler; // nothing by default.
317  if (ole_auto_registering())
318  special_filler = "VALUE \"OLESelfRegister\", \"\\0\"";
319  REPLACE("$special_ole_flag", special_filler);
320 
321  astring root_part = "/";
322  root_part += _ini->load(VERSION_SECTION, ROOT, "");
323 
324  astring rc_filename(header_store + "/" + root_part
325  + "_version.rc");
326 
327  filename(rc_filename).chmod(filename::ALLOW_BOTH, filename::USER_RIGHTS);
328  // make sure we can write to the file.
329 
330  byte_filer rc_file(rc_filename, "w");
331  if (!rc_file.good()) return false;
332  rc_file.write((abyte *)new_version_entry.s(), new_version_entry.length());
333  rc_file.close();
334  return true;
335 }
336 
338 
340 #ifndef $lib_prefix_VERSION_HEADER\n\
341 #define $lib_prefix_VERSION_HEADER\n\
342 \n\
343 /*****************************************************************************\\\n\
344 * *\n\
345 * Name : Version header for $lib_name\n\
346 * Author : Automatically generated by version_stamper *\n\
347 * *\n\
348 \\*****************************************************************************/\n\
349 \n\
350 #include <__build_version.h>\n\
351 #include <__build_configuration.h>\n\
352 #include <basis/version_checker.h>\n\
353 #include <basis/version_record.h>\n\
354 \n\
355 #ifdef __WIN32__\n\
356 \n\
357 // this macro can be used to check that the current version of the\n\
358 // $lib_name library is the same version as expected. to use it, check\n\
359 // whether it returns true or false. if false, the version is incorrect.\n\
360 #define CHECK_$lib_prefix() (version_checker(astring(\"$lib_prefix\")\\\n\
361  + astring(\".dll\"), version(__build_SYSTEM_VERSION),\\\n\
362  astring(\"Please contact $company_name for the latest DLL and \"\\\n\
363  \"Executable files ($web_address).\")).good_version())\n\
364 \n\
365 #else\n\
366 \n\
367 // null checking for embedded or other platforms without versions.\n\
368 \n\
369 #define CHECK_$lib_prefix() 1\n\
370 \n\
371 #endif //__WIN32__\n\
372 \n\
373 #endif\n\
374 \n";
375 
377 
378 bool version_ini::write_code(const astring &header_store, const version_record &to_write)
379 {
380  FUNCDEF("write_code");
381  astring root_part = _ini->load(VERSION_SECTION, ROOT, "");
382  astring root = root_part.upper(); // make upper case for naming sake.
383  astring name = _ini->load(VERSION_SECTION, NAME, "");
384  // replace the macros here also.
385  name.replace_all("$product_name", to_write.product_name);
386 
387  astring new_version_entry(version_header_template);
388 
389 //some of the replacements are no longer needed.
390 
391  // $lib_prefix -> the first part of the library's name.
392  REPLACE("$lib_prefix", root);
393  REPLACE("$lib_prefix", root);
394  REPLACE("$lib_prefix", root);
395  REPLACE("$lib_prefix", root);
396  REPLACE("$lib_prefix", root);
397  REPLACE("$lib_prefix", root);
398  REPLACE("$lib_prefix", root);
399 
400  // $lib_name -> the name of the library, as it thinks of itself.
401  REPLACE("$lib_name", name);
402  REPLACE("$lib_name", name);
403  REPLACE("$lib_name", name);
404 
405  // $lib_version -> the current version for this library.
406  REPLACE("$lib_version", to_write.file_version.flex_text_form(version::COMMAS));
407 
408  // $company_name -> the company that produces the library.
409  REPLACE("$company_name", to_write.company_name);
410 
411  // $web_address -> the web site for the company. not actually stored.
412  REPLACE("$web_address", to_write.web_address);
413 
414  astring header_filename(header_store + "/" + root_part
415  + astring("_version.h"));
416 
417  filename(header_filename).chmod(filename::ALLOW_BOTH, filename::USER_RIGHTS);
418  // make sure we can write to the file.
419 
420  byte_filer header(header_filename, "w");
421  if (!header.good()) return false;
422  header.write((abyte *)new_version_entry.s(), new_version_entry.length());
423  header.close();
424  return true;
425 }
426 
427 
428 // returns true if manipulated the full_string to replace its version
429 bool replace_version_entry(astring &full_string, const astring &look_for,
430  const astring &new_ver)
431 {
432  bool to_return = false;
433  int posn = 0; // where are we looking for this?
434 
435  while (posn < full_string.length()) {
436  int ver_posn = full_string.find(look_for, posn);
437  if (ver_posn < 0) break; // nothing to modify.
438  int quote_posn = full_string.find("\"", ver_posn);
439  if (quote_posn < 0) break; // malformed assembly we will not touch.
440  int second_quote_posn = full_string.find("\"", quote_posn + 1);
441  if (second_quote_posn < 0) break; // more malformage.
442  full_string.zap(quote_posn + 1, second_quote_posn - 1);
443  full_string.insert(quote_posn + 1, new_ver);
444  to_return = true; // found a match.
445  // skip to the next place.
446  posn = quote_posn + new_ver.length();
447  }
448 
449  return to_return;
450 }
451 
452 bool version_ini::write_assembly(const astring &header_store, const version_record &to_write,
453  bool do_logging)
454 {
455  FUNCDEF("write_assembly");
456  filename just_dir = filename(header_store);
457  //_path_name->dirname();
458 
459 //hmmm: make condit on debug
460 LOG(astring("dir is set to: ") + just_dir);
461 
462  directory dir(just_dir);
463  filename to_patch;
464 //LOG(astring("dir has: ") + dir.files().text_form());
465  if (non_negative(dir.files().find("AssemblyInfo.cpp")))
466  to_patch = just_dir.raw() + "/AssemblyInfo.cpp";
467  else if (non_negative(dir.files().find("AssemblyInfo.cs")))
468  to_patch = just_dir.raw() + "/AssemblyInfo.cs";
469  if (!to_patch.raw()) {
470  // no assembly file yet. see if there's one in a properties subdirectory.
471  directory dir2(just_dir + "/Properties");
472  if (non_negative(dir2.files().find("AssemblyInfo.cpp")))
473  to_patch = just_dir.raw() + "/Properties/AssemblyInfo.cpp";
474  else if (non_negative(dir2.files().find("AssemblyInfo.cs")))
475  to_patch = just_dir.raw() + "/Properties/AssemblyInfo.cs";
476  }
477 
478  if (to_patch.raw().t()) {
479  // we have a filename to work on.
480  filename(to_patch).chmod(filename::ALLOW_BOTH, filename::USER_RIGHTS);
481  // make sure we can write to the file.
482  byte_filer modfile(to_patch, "r+b");
483  astring contents;
484  modfile.read(contents, 1000000); // read any file size up to that.
485  while (contents[contents.end()] == '\032') {
486  // erase any stray eof characters that may happen to be present.
487  contents.zap(contents.end(), contents.end());
488  }
489 //LOG(astring("file contents are: \n") + contents);
490 
491 //here's where to fixit.
492 
493  astring ver_string = to_write.file_version.flex_text_form(version::DOTS);
494  bool did_replace = replace_version_entry(contents, "AssemblyVersionAttribute", ver_string);
495  if (!did_replace) {
496  did_replace = replace_version_entry(contents, "AssemblyVersion", ver_string);
497  }
498  if (!did_replace) return true; // nothing to modify?
499  did_replace = replace_version_entry(contents, "AssemblyFileVersion", ver_string);
500  if (!did_replace) {
501  did_replace = replace_version_entry(contents, "AssemblyFileVersionAttribute", ver_string);
502  }
503  // if we got to here, we at least replaced something...
504 
505 /*
506  int ver_posn = contents.find("AssemblyVersionAttribute", 0);
507  // try again if that seek failed.
508  if (ver_posn < 0)
509  ver_posn = contents.find("AssemblyVersion", 0);
510  if (ver_posn < 0) return true; // nothing to modify.
511 //LOG(astring("found assembly version: ") + to_patch);
512  int quote_posn = contents.find("\"", ver_posn);
513  if (quote_posn < 0) return true; // malformed assembly we will not touch.
514 //LOG(astring("found quote: ") + to_patch);
515  int second_quote_posn = contents.find("\"", quote_posn + 1);
516  if (second_quote_posn < 0) return true; // more malformage.
517 //LOG(astring("found quote: ") + to_patch);
518  contents.zap(quote_posn + 1, second_quote_posn - 1);
519  contents.insert(quote_posn + 1, ver_string);
520 */
521 
522 //LOG(astring("writing new output file: ") + to_patch);
523  modfile.seek(0);
524  modfile.write(contents);
525  modfile.truncate(); // chop off anything left from previous versions.
526  if (do_logging) {
527  // let the people know about this...
528  filename dirbase = filename(modfile.name()).dirname().basename();
529  filename just_base = filename(modfile.name()).basename();
530  program_wide_logger::get().log(astring(" patching: ") + dirbase
531  + "/" + just_base, basis::ALWAYS_PRINT);
532  }
533  }
534 
535  return true;
536 }
537 
539  const astring &header_store, const astring &source_version, bool do_logging)
540 {
541  FUNCDEF("one_stop_version_stamp");
542  astring path_name = path;
543  if (path_name.equal_to("."))
544  path_name = application_configuration::current_directory();
545 
546  // load the version record in from the ini file and cache it.
547  version_ini source(path_name);
548  source.get_record();
549 
550  if (source_version.t()) {
551  // get the version structure from the passed file.
552  version_ini main_version(source_version);
553  version version_to_use = main_version.get_version();
554 
555  // stuff the version from the main source into this particular file.
556  source.set_version(version_to_use, false);
557 
558  // stuff the other volatile records from the main version.
559  version_record main = main_version.get_record();
560  source.access_record().company_name = main.company_name;
561  source.access_record().web_address = main.web_address;
562  source.access_record().copyright = main.copyright;
563  source.access_record().trademarks = main.trademarks;
564  source.access_record().product_name = main.product_name;
565 
566  source.access_record().internal_name.replace("$product_name",
567  source.get_record().product_name);
568  }
569 
570  if (do_logging) {
571  // report the current state.
572  program_wide_logger::get().log(source.get_record().internal_name + " version "
573  + source.get_version().text_form() + ".", ALWAYS_PRINT);
574  }
575 
576  version_ini verini(path_name);
577  verini.set_record(source.get_record(), false);
578 
579 //put this in debug brackets
580  LOG(a_sprintf("The file \"%s\" contains this version information:",
581  path_name.s()));
582  LOG(verini.get_record().text_form());
583 //...debug to here
584 
585  if (!verini.write_rc(header_store, verini.get_record())) {
586  critical_events::alert_message(a_sprintf("Could not write the RC file in \"%s\".",
587  filename(path_name).basename().raw().s()));
588  return false;
589  }
590 
591  if (verini.library() && !verini.write_code(header_store, verini.get_record())) {
592  critical_events::alert_message(astring("Could not write the C++ header file for "
593  "the directory \"")
594  + filename(path_name).basename() + astring("\".\n"));
595  return false;
596  }
597 
598  if (!verini.write_assembly(header_store, verini.get_record(), do_logging)) {
599  critical_events::alert_message(astring("Could not write the Assembly info file for "
600  "the directory \"")
601  + filename(path_name).basename() + astring("\".\n"));
602  return false;
603  }
604 
605  return true;
606 }
607 
608 } //namespace.
a_sprintf is a specialization of astring that provides printf style support.
Definition: astring.h:440
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
Definition: astring.h:113
astring lower() const
like to_lower(), but returns a new string rather than modifying this.
Definition: astring.cpp:542
bool t() const
t() is a shortcut for the string being "true", as in non-empty.
Definition: astring.h:97
bool replace(const astring &tag, const astring &replacement)
replaces the first occurrence of "tag" text with the "replacement".
Definition: astring.cpp:905
virtual void zap(int start, int end)
Deletes the characters between "start" and "end" inclusively.
Definition: astring.cpp:521
void insert(int position, const astring &to_insert)
Copies "to_insert" into "this" at the "position".
Definition: astring.cpp:892
bool equal_to(const char *that) const
returns true if "that" is equal to this.
Definition: astring.cpp:159
int end() const
returns the index of the last (non-null) character in the string.
Definition: astring.h:86
bool replace_all(char to_replace, char new_char)
changes all occurrences of "to_replace" with "new_char".
Definition: astring.cpp:929
int length() const
Returns the current length of the string.
Definition: astring.cpp:132
astring upper() const
like to_upper(), but returns a new string rather than modifying this.
Definition: astring.cpp:549
int find(char to_find, int position=0, bool reverse=false) const
Locates "to_find" in "this".
Definition: astring.cpp:574
void to_lower()
to_lower modifies "this" by replacing capitals with lower-case.
Definition: astring.cpp:528
bool store(const basis::astring &section, const basis::astring &entry, const basis::astring &to_store)
a synonym for put.
basis::astring load(const basis::astring &section, const basis::astring &entry, const basis::astring &default_value)
a synonym for get that implements the auto-store behavior.
Supports a configurator-based interface on text initialization files.
basis::astring name() const
observes the name of the file used for ini entries.
Provides file managment services using the standard I/O support.
Definition: byte_filer.h:32
int write(const basis::abyte *buffer, int buffer_size)
writes "buffer_size" bytes into the file from "buffer".
Definition: byte_filer.cpp:126
void close()
shuts down the open file, if any.
Definition: byte_filer.cpp:96
bool seek(int where, origins origin=FROM_START)
places the cursor in the file at "where", based on the "origin".
Definition: byte_filer.cpp:187
const basis::astring & name() const
returns the file name that the object is operating on.
Definition: byte_filer.cpp:82
int read(basis::abyte *buffer, int buffer_size)
reads "buffer_size" bytes from the file into "buffer".
Definition: byte_filer.cpp:123
bool truncate()
truncates the file after the current position.
Definition: byte_filer.cpp:171
bool good()
returns true if the file seems to be in the appropriate desired state.
Definition: byte_filer.cpp:103
Implements a scanner that finds all filenames in the directory specified.
Definition: directory.h:27
const structures::string_array & files() const
returns the list of files that we found in this directory.
Definition: directory.cpp:143
Provides operations commonly needed on file names.
Definition: filename.h:64
void canonicalize()
cleans up the filename as needed for the current operating system.
Definition: filename.cpp:157
bool chmod(int write_mode, int owner_mode) const
changes the access rights on the file.
Definition: filename.cpp:624
bool is_directory() const
Definition: filename.cpp:325
bool is_writable() const
Definition: filename.cpp:333
const basis::astring & raw() const
returns the astring that we're holding onto for the path.
Definition: filename.cpp:97
filename dirname() const
returns the directory for the filename.
Definition: filename.cpp:393
filename basename() const
returns the base of the filename; no directory.
Definition: filename.cpp:385
An array of strings with some additional helpful methods.
Definition: string_array.h:32
int find(const basis::astring &to_find) const
locates string specified and returns its index, or negative if missing.
Definition: string_array.h:88
Holds all information about a file's versioning.
basis::astring text_form() const
Holds a file's version identifier.
virtual basis::astring text_form() const
basis::astring get_component(int index) const
returns the component at the specified index.
void set_component(int index, const basis::astring &to_set)
sets the component at "index" to "to_set".
basis::astring flex_text_form(version_style style=DOTS, int including=-1) const
returns a textual form of the version number.
This provides support for writing windows version files.
Definition: version_ini.h:33
static const char * EXTENSION
Definition: version_ini.h:129
structures::version read_version_from_ini()
specialized version ignores cache and gets version directly from file.
structures::version get_version()
observes or modifies the version number structure held here.
bool write_code(const basis::astring &header_store, const structures::version_record &to_write)
writes out the header ('X_version.h') with the version information.
static const char * ROOT
Definition: version_ini.h:127
static const char * PRODUCT_KEY
Definition: version_ini.h:120
void set_record(const structures::version_record &to_write, bool write_to_ini)
modifies the entire version record.
static const char * COMPANY_KEY
Definition: version_ini.h:117
void set_version(const structures::version &to_write, bool write_to_ini)
sets the version held here.
bool write_assembly(const basis::astring &header_store, const structures::version_record &to_write, bool do_logging)
fixes any assemblies with the info in "to_write".
static bool one_stop_version_stamp(const basis::astring &path, const basis::astring &header_store, const basis::astring &source_version, bool do_logging)
performs version stamping using the ini file in "path".
static const char * DESCRIPTION
Definition: version_ini.h:126
structures::version_record get_record()
observes the entire version record.
static const char * NAME
Definition: version_ini.h:128
bool library()
returns true if this version file is for a dynamic library.
static const char * COPYRIGHT_KEY
Definition: version_ini.h:118
static const char * MINOR
Definition: version_ini.h:123
bool writable()
returns true if the INI file specified in the constructor is writable.
static const char * LEGAL_INFO_KEY
Definition: version_ini.h:119
static const char * REVISION
Definition: version_ini.h:124
static const char * OLE_AUTO
Definition: version_ini.h:130
static const char * MAJOR
Definition: version_ini.h:122
static const char * WEB_SITE_KEY
Definition: version_ini.h:121
static const char * BUILD
Definition: version_ini.h:125
static const char * VERSION_SECTION
Definition: version_ini.h:116
bool ole_auto_registering()
returns true if this version file specifies ole auto registration.
Definition: version_ini.cpp:87
bool write_rc(const basis::astring &header_store, const structures::version_record &to_write)
writes out the file 'X_version.rc' for the X library or application.
bool executable()
returns true if this version file is for an executable.
Definition: version_ini.cpp:93
structures::version_record & access_record()
provides access to change the version_record held here.
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition: enhance_cpp.h:57
The guards collection helps in testing preconditions and reporting errors.
Definition: array.h:30
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
Definition: functions.h:121
unsigned char abyte
A fairly important unit which is seldom defined...
Definition: definitions.h:51
bool non_negative(const type &a)
non_negative returns true if "a" is greater than or equal to zero.
Definition: functions.h:45
string path
Definition: eml_to_txt.py:139
A platform independent way to obtain the timestamp of a file.
Definition: byte_filer.cpp:37
A logger that sends to the console screen using the standard output device.
A dynamic container class that holds any kind of object via pointers.
Definition: amorph.h:55
const astring version_header_template
bool replace_version_entry(astring &full_string, const astring &look_for, const astring &new_ver)
const astring version_rc_template
const char * VERSION_INI_FILE
Definition: version_ini.cpp:65
#define REPLACE(tag, replacement)
#define LOG(t)
Definition: version_ini.cpp:68