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
17namespace base {
18
19std::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