]>
Commit | Line | Data |
---|---|---|
a47815fb DB |
1 | /* |
2 | Compile-server and client common functions | |
3 | Copyright (C) 2011 Red Hat Inc. | |
4 | ||
5 | This file is part of systemtap, and is free software. You can | |
6 | redistribute it and/or modify it under the terms of the GNU General | |
7 | Public License (GPL); either version 2, or (at your option) any | |
8 | later version. | |
9 | */ | |
10 | #include "util.h" | |
11 | #include "cscommon.h" | |
12 | ||
13 | #include <fstream> | |
14 | #include <string> | |
15 | #include <vector> | |
16 | #include <cstdlib> | |
17 | #include <cstring> | |
18 | #include <cassert> | |
19 | ||
20 | using namespace std; | |
21 | ||
22 | cs_protocol_version::~cs_protocol_version () | |
23 | { | |
24 | assert (this->v); | |
25 | free ((void*)this->v); | |
26 | } | |
27 | ||
28 | const cs_protocol_version & | |
29 | cs_protocol_version::operator= (const char *v) | |
30 | { | |
31 | if (this->v) | |
32 | free ((void *)this->v); | |
33 | this->v = strdup (v); | |
34 | return *this; | |
35 | } | |
36 | ||
37 | bool | |
38 | cs_protocol_version::operator< (const cs_protocol_version &that) const | |
39 | { | |
40 | // Compare the levels of each version in turn. | |
41 | vector<string> these_tokens; | |
42 | tokenize (this->v, these_tokens, "."); | |
43 | vector<string> those_tokens; | |
44 | tokenize (that.v, those_tokens, "."); | |
45 | ||
46 | unsigned this_limit = these_tokens.size (); | |
47 | unsigned that_limit = those_tokens.size (); | |
48 | unsigned i; | |
49 | for (i = 0; i < this_limit && i < that_limit; ++i) | |
50 | { | |
51 | char *e; | |
52 | unsigned long this_level = strtoul (these_tokens[i].c_str (), & e, 0); | |
53 | assert (! *e); | |
54 | unsigned long that_level = strtoul (those_tokens[i].c_str (), & e, 0); | |
55 | assert (! *e); | |
56 | if (this_level > that_level) | |
57 | return false; | |
58 | if (this_level < that_level) | |
59 | return true; | |
60 | } | |
61 | ||
62 | // If the other version has more components, then this one is less than that one. | |
63 | if (i < that_limit) | |
64 | { | |
65 | assert (i == this_limit); | |
66 | return true; | |
67 | } | |
68 | // This version is greater than or equal to that one. | |
69 | return false; | |
70 | } | |
71 | ||
72 | int | |
73 | read_from_file (const string &fname, cs_protocol_version &data) | |
74 | { | |
75 | // C++ streams may not set errno in the even of a failure. However if we | |
76 | // set it to 0 before each operation and it gets set during the operation, | |
77 | // then we can use its value in order to determine what happened. | |
78 | string dataStr; | |
79 | errno = 0; | |
80 | ifstream f (fname.c_str ()); | |
81 | if (! f.good ()) | |
82 | { | |
83 | clog << _F("Unable to open file '%s' for reading: ", fname.c_str()); | |
84 | goto error; | |
85 | } | |
86 | ||
87 | // Read the data; | |
88 | errno = 0; | |
89 | f >> dataStr; | |
90 | if (f.fail ()) | |
91 | { | |
92 | clog << _F("Unable to read from file '%s': ", fname.c_str()); | |
93 | goto error; | |
94 | } | |
95 | ||
96 | data = dataStr.c_str (); | |
97 | ||
98 | // NB: not necessary to f.close (); | |
99 | return 0; // Success | |
100 | ||
101 | error: | |
102 | if (errno) | |
103 | clog << strerror (errno) << endl; | |
104 | else | |
105 | clog << _("unknown error") << endl; | |
106 | return 1; // Failure | |
107 | } | |
108 |