first check-in of feisty meow codebase. many things broken still due to recent
[feisty_meow.git] / core / library / structures / version_record.cpp
1 /*****************************************************************************\
2 *                                                                             *
3 *  Name   : version structures: version, version_record                       *
4 *  Author : Chris Koeritz                                                     *
5 *                                                                             *
6 *******************************************************************************
7 * Copyright (c) 1996-$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 "string_array.h"
16 #include "version_record.h"
17
18 #include <basis/functions.h>
19
20 #include <ctype.h>
21
22 using namespace basis;
23
24 namespace structures {
25
26 void *version::__global_module_handle()
27 {
28   static void *__mod_hand = 0;
29   return __mod_hand;
30 }
31
32 version::version()
33 : _components(new string_array)
34 {
35   set_component(MAJOR, "0");
36   set_component(MINOR, "0");
37   set_component(REVISION, "0");
38   set_component(BUILD, "0");
39 }
40
41 version::version(const string_array &version_info)
42 : _components(new string_array(version_info))
43 {
44   for (int i = 0; i < _components->length(); i++) {
45     if (!(*_components)[i]) {
46       // this component is blank; replace it with a zero.
47       (*_components)[i] = "0";
48     }
49   }
50 }
51
52 version::version(const astring &formatted_string)
53 : _components(new string_array)
54 {
55   astring verstring = formatted_string;
56   // scan through and replace bogus bits with reasonable bits.
57   for (int j = 0; j < verstring.length(); j++) {
58     if (verstring[j] == ',') verstring[j] = '.';
59       // replace commas with periods.
60   }
61   // locate the pieces of the version string.
62   for (int i = 0; i < verstring.length(); i++) {
63     int perindy = verstring.find('.', i);
64     if (negative(perindy)) {
65       if (verstring.length() - i > 0) {
66         // add any extra bits after the last period in the string.
67         *_components += verstring.substring(i, verstring.end());
68       }
69       break;
70     }
71     // we found a period, so include anything between the current position and
72     // that as a component.
73     *_components += verstring.substring(i, perindy - 1);
74     i = perindy;
75       // set i to be at the next period; it will be incremented past that.
76   }
77 }
78
79 version::version(int maj, int min, int rev, int build)
80 : _components(new string_array)
81 {
82   *this = version(a_sprintf("%u.%u.%u.%u", basis::un_int(maj), basis::un_int(min), basis::un_int(rev),
83       basis::un_int(build)));
84 }
85
86 version::version(const version &to_copy)
87 : _components(new string_array)
88 { *this = to_copy; }
89
90 version::~version() { WHACK(_components); }
91
92 version &version::operator =(const version &to_copy)
93 {
94   if (this != &to_copy) *_components = *to_copy._components;
95   return *this;
96 }
97
98 astring version::text_form() const { return flex_text_form(); }
99
100 int version::components() const { return _components->length(); }
101
102 int version::v_major() const
103 { return int(get_component(MAJOR).convert(0)); }
104
105 int version::v_minor() const
106 { return int(get_component(MINOR).convert(0)); }
107
108 int version::v_revision() const
109 { return int(get_component(REVISION).convert(0)); }
110
111 int version::v_build() const
112 { return int(get_component(BUILD).convert(0)); }
113
114 astring version::get_component(int index) const
115 {
116   bounds_return(index, 0, _components->length() - 1, "0");
117   return (*_components)[index];
118 }
119
120 void version::set_component(int index, const astring &to_set)
121 {
122   if (_components->length() <= index)
123     _components->resize(index + 1);
124   if (to_set.t())
125     (*_components)[index] = to_set;
126   else
127     (*_components)[index] = "0";
128 }
129
130 bool version::equal_to(const equalizable &to_test) const
131 {
132   const version *cast = cast_or_throw(to_test, *this);
133   return *_components == *cast->_components;
134 }
135
136 bool version::less_than(const orderable &to_test) const
137 {
138   const version *cast = cast_or_throw(to_test, *this);
139   if (v_major() < cast->v_major()) return true;
140   else if (v_major() > cast->v_major()) return false;
141   if (v_minor() < cast->v_minor()) return true;
142   else if (v_minor() > cast->v_minor()) return false;
143   if (v_revision() < cast->v_revision()) return true;
144   else if (v_revision() > cast->v_revision()) return false;
145   if (v_build() < cast->v_build()) return true;
146   return false;
147 }
148
149 bool version::compatible(const version &to_test) const
150 {
151 //fix to be more general
152   return (v_major() == to_test.v_major())
153       && (v_minor() == to_test.v_minor())
154       && (v_revision() == to_test.v_revision());
155 }
156
157 bool version::bogus() const
158 { return !v_major() && !v_minor() && !v_revision() && !v_build(); }
159
160 #define SEPARATE \
161   if (style != DOTS) to_return += ", "; \
162   else to_return += "."
163
164 astring version::flex_text_form(version_style style, int where) const
165 {
166   // note: the conversions below are to ensure proper treatment of the
167   // size of the int16 types by win32.
168   astring to_return;
169
170   if (style == DETAILED) to_return += "major ";
171   astring temp = get_component(MAJOR);
172   if (!temp) temp = "0";
173   to_return += temp;
174   if (where == MAJOR) return to_return;
175   SEPARATE;
176
177   if (style == DETAILED) to_return += "minor ";
178   temp = get_component(MINOR);
179   if (!temp) temp = "0";
180   to_return += temp;
181   if (where == MINOR) return to_return;
182   SEPARATE;
183
184   if (style == DETAILED) to_return += "revision ";
185   temp = get_component(REVISION);
186   if (!temp) temp = "0";
187   to_return += temp;
188   if (where == REVISION) return to_return;
189   SEPARATE;
190
191   if (style == DETAILED) to_return += "build ";
192   temp = get_component(BUILD);
193   if (!temp) temp = "0";
194   to_return += temp;
195
196   // other components don't have handy names.
197   if (where > BUILD) {
198     for (int i = BUILD + 1; i < where; i++) {
199       SEPARATE;
200       if (style == DETAILED) to_return += a_sprintf("part_%d ", i + 1);
201       temp = get_component(i);
202       if (!temp) temp = "0";
203       to_return += temp;
204     }
205   }
206
207   return to_return;
208 }
209
210 version version::from_text(const astring &to_convert)
211 { return version(to_convert); }
212
213 int version::packed_size() const
214 {
215   return _components->packed_size();
216 }
217
218 void version::pack(byte_array &target) const
219 { _components->pack(target); }
220
221 bool version::unpack(byte_array &source)
222 {
223   if (!_components->unpack(source)) return false;
224   return true;
225 }
226
227 //////////////
228
229 #define VR_NEWLINE to_return += "\n"
230
231 version_record::~version_record()
232 {}
233
234 astring version_record::text_form() const
235 {
236   astring to_return;
237   to_return += "Description: ";
238   to_return += description;
239   VR_NEWLINE;
240   to_return += "File Version: ";
241   to_return += file_version.text_form();
242   VR_NEWLINE;
243   to_return += "Internal Name: ";
244   to_return += internal_name;
245   VR_NEWLINE;
246   to_return += "Original Name: ";
247   to_return += original_name;
248   VR_NEWLINE;
249   to_return += "Product Name: ";
250   to_return += product_name;
251   VR_NEWLINE;
252   to_return += "Product Version: ";
253   to_return += product_version.text_form();
254   VR_NEWLINE;
255   to_return += "Company Name: ";
256   to_return += company_name;
257   VR_NEWLINE;
258   to_return += "Copyright: ";
259   to_return += copyright;
260   VR_NEWLINE;
261   to_return += "Trademarks: ";
262   to_return += trademarks;
263   VR_NEWLINE;
264
265   return to_return;
266 }
267
268 } //namespace.
269