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>
22#include <filesystem/filename.h>
26
27#include <sys/stat.h>
28#ifdef __WIN32__
29 #include <io.h>
30#endif
31
32using namespace basis;
33using namespace configuration;
34using namespace filesystem;
35using namespace loggers;
36using namespace structures;
37
38namespace versions {
39
40// the following are all strings that are sought in the version.ini file.
41const char *version_ini::VERSION_SECTION = "version";
42 // the section that version entries are stored under in the INI file.
43const char *version_ini::COMPANY_KEY="company";
44const char *version_ini::COPYRIGHT_KEY="copyright";
45const char *version_ini::LEGAL_INFO_KEY="legal_info";
46const char *version_ini::PRODUCT_KEY="product_name";
47const 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.
54const char *version_ini::MAJOR = "major";
55const char *version_ini::MINOR = "minor";
56const char *version_ini::REVISION = "revision";
57const char *version_ini::BUILD = "build";
58const char *version_ini::DESCRIPTION = "description";
59const char *version_ini::ROOT = "root";
60const char *version_ini::NAME = "name";
61const char *version_ini::EXTENSION = "extension";
62const char *version_ini::OLE_AUTO = "ole_auto";
63
64// this is the default version INI file name, if no other is specified.
65const char *VERSION_INI_FILE = "/version.ini";
66
67#undef LOG
68#define LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t)
69
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
100bool version_ini::library() { return !executable(); }
101
102bool version_ini::writable() { return _path_name->is_writable(); }
103
104void 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
120bool 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
131bool 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
141void 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;
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.
155}
156
158{
159 string_array parts;
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
167version_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, "");
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;
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
204void version_ini::set_record(const version_record &to_write, bool write_ini)
205{
206 *_held_record = to_write;
207 if (write_ini) {
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\
2251 VERSIONINFO LOADONCALL MOVEABLE\n\
226FILEVERSION __build_FILE_VERSION_COMMAS\n\
227PRODUCTVERSION __build_PRODUCT_VERSION_COMMAS\n\
228FILEFLAGSMASK 0\n\
229FILEFLAGS 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\
235FILETYPE VFT_APP\n\
236BEGIN\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\
263END\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
272bool 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
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
315
316 astring special_filler; // nothing by default.
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
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
378bool 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
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
429bool 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
452bool 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
460LOG(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.
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("."))
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.
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.
#define LOG(s)
int main(int argc, char *argv[])
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
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:908
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
Definition astring.h:113
virtual void zap(int start, int end)
Deletes the characters between "start" and "end" inclusively.
Definition astring.cpp:524
void insert(int position, const astring &to_insert)
Copies "to_insert" into "this" at the "position".
Definition astring.cpp:895
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
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:552
int find(char to_find, int position=0, bool reverse=false) const
Locates "to_find" in "this".
Definition astring.cpp:577
virtual outcome log(const base_string &info, int filter)=0
writes the information in "info" to the logger using the "filter".
static basis::astring current_directory()
returns the current directory as reported by the operating system.
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".
void close()
shuts down the open file, if any.
bool seek(int where, origins origin=FROM_START)
places the cursor in the file at "where", based on the "origin".
const basis::astring & name() const
returns the file name that the object is operating on.
int read(basis::abyte *buffer, int buffer_size)
reads "buffer_size" bytes from the file into "buffer".
bool truncate()
truncates the file after the current position.
bool good()
returns true if the file seems to be in the appropriate desired state.
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.
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
static void alert_message(const char *info, const char *title="Alert Message")
shows the message in "info", with an optional "title" on the message.
static loggers::standard_log_base & get()
Provided by the startup code within each application for logging.
An array of strings with some additional helpful methods.
int find(const basis::astring &to_find) const
locates string specified and returns its index, or negative if missing.
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
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
static const char * PRODUCT_KEY
void set_record(const structures::version_record &to_write, bool write_to_ini)
modifies the entire version record.
static const char * COMPANY_KEY
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
structures::version_record get_record()
observes the entire version record.
static const char * NAME
bool library()
returns true if this version file is for a dynamic library.
static const char * COPYRIGHT_KEY
static const char * MINOR
bool writable()
returns true if the INI file specified in the constructor is writable.
static const char * LEGAL_INFO_KEY
static const char * REVISION
static const char * OLE_AUTO
static const char * MAJOR
static const char * WEB_SITE_KEY
static const char * BUILD
static const char * VERSION_SECTION
bool ole_auto_registering()
returns true if this version file specifies ole auto registration.
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.
version_ini(const basis::astring &path_name)
the "path_name" is where the version INI file is located.
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:54
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
A platform independent way to obtain the timestamp of a file.
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
#define REPLACE(tag, replacement)