1 | // LAF Base Library |
2 | // Copyright (c) 2021 Igara Studio S.A. |
3 | // |
4 | // This file is released under the terms of the MIT license. |
5 | // Read LICENSE.txt for more information. |
6 | |
7 | #ifdef HAVE_CONFIG_H |
8 | #include "config.h" |
9 | #endif |
10 | |
11 | #include "base/platform.h" |
12 | |
13 | #include "base/file_handle.h" |
14 | |
15 | #include <cstdio> |
16 | |
17 | namespace base { |
18 | |
19 | std::map<std::string, std::string> get_linux_release_info(const std::string& fn) |
20 | { |
21 | std::map<std::string, std::string> values; |
22 | |
23 | FileHandle f(open_file(fn.c_str(), "r" )); |
24 | if (!f) |
25 | return values; |
26 | |
27 | std::vector<char> buf(1024); |
28 | std::string value; |
29 | |
30 | while (std::fgets(&buf[0], buf.size(), f.get())) { |
31 | for (auto i=buf.begin(), end=buf.end(); i != end; ++i) { |
32 | // Commented line |
33 | if (*i == '#') |
34 | break; |
35 | // Ignore initial whitespace |
36 | else if (*i == ' ') |
37 | continue; |
38 | // Read the key |
39 | else if (*i >= 'A' && *i <= 'Z') { |
40 | auto j = i; |
41 | while (j != end && ((*j >= 'A' && *j <= 'Z') || |
42 | (*j >= '0' && *j <= '9') || (*j == '_'))) { |
43 | ++j; |
44 | } |
45 | |
46 | std::string key(i, j); |
47 | |
48 | // Ignore white space between "KEY ... =" |
49 | while (j != end && *j == ' ') |
50 | ++j; |
51 | if (j != end && *j == '=') { |
52 | ++j; // Skip '=' |
53 | // Ignore white space between "KEY= ... VALUE" |
54 | while (j != end && *j == ' ') |
55 | ++j; |
56 | |
57 | value.clear(); |
58 | |
59 | if (j != end) { |
60 | char quote = *j; |
61 | if (quote == '\'' || quote == '\"') { |
62 | ++j; |
63 | while (j != end && *j != quote) { |
64 | if (*j == '\\') { |
65 | ++j; |
66 | if (j == end) |
67 | break; |
68 | } |
69 | value.push_back(*j); |
70 | ++j; |
71 | } |
72 | } |
73 | else { |
74 | while (j != end && (*j != ' ' && |
75 | *j != '\r' && |
76 | *j != '\n')) { |
77 | value.push_back(*j); |
78 | ++j; |
79 | } |
80 | } |
81 | } |
82 | |
83 | values[key] = value; |
84 | } |
85 | break; // Next line |
86 | } |
87 | // Unexpected character in this line |
88 | else { |
89 | break; |
90 | } |
91 | } |
92 | |
93 | // Too many key-values |
94 | if (values.size() > 4096) |
95 | break; |
96 | } |
97 | |
98 | return values; |
99 | } |
100 | |
101 | } // namespace base |
102 | |