@@ -33,8 +33,6 @@ namespace detail {
33
33
#include " detail/config.def"
34
34
#undef CONFIG
35
35
36
- #define MAX_CONFIG_NAME 256
37
-
38
36
static void initValue (const char *Key, const char *Value) {
39
37
#define CONFIG (Name, MaxSize, CompileTimeDef ) \
40
38
if (0 == strncmp (Key, SYCLConfigBase<Name>::MConfigName, MAX_CONFIG_NAME)) { \
@@ -47,10 +45,11 @@ static void initValue(const char *Key, const char *Value) {
47
45
#undef CONFIG
48
46
}
49
47
50
- void readConfig () {
48
+ void readConfig (bool ForceInitialization ) {
51
49
static bool Initialized = false ;
52
- if (Initialized)
50
+ if (!ForceInitialization && Initialized) {
53
51
return ;
52
+ }
54
53
55
54
std::fstream File;
56
55
if (const char *ConfigFile = getenv (" SYCL_CONFIG_FILE_NAME" ))
@@ -62,39 +61,85 @@ void readConfig() {
62
61
}
63
62
64
63
if (File.is_open ()) {
65
- // TODO: Use max size from macro instead of 256
66
- char Key[MAX_CONFIG_NAME] = {0 }, Value[256 ] = {0 };
64
+ char Key[MAX_CONFIG_NAME] = {0 }, Value[MAX_CONFIG_VALUE] = {0 };
65
+ std::string BufString;
66
+ std::size_t Position = std::string::npos;
67
67
while (!File.eof ()) {
68
- // Expected fromat :
68
+ // Expected format :
69
69
// ConfigName=Value\r
70
+ // ConfigName=Value #comment
70
71
// ConfigName=Value
71
72
// TODO: Skip spaces before and after '='
72
- File.getline (Key, sizeof (Key), ' =' );
73
- if (File.fail ()) {
74
- // Fail to process the line. Skip it completely and try next one.
75
- // Do we want to restore here? Or just throw an exception?
73
+ std::getline (File, BufString);
74
+ if (File.fail () && !File.eof ()) {
75
+ // Fail to process the line.
76
76
File.clear (File.rdstate () & ~std::ios_base::failbit);
77
77
File.ignore (std::numeric_limits<std::streamsize>::max (), ' \n ' );
78
+ throw sycl::exception (
79
+ make_error_code (errc::runtime),
80
+ " An error occurred while attempting to read a line" );
81
+ }
82
+ // Handle '\r'
83
+ if ((BufString.length () > 0 ) &&
84
+ (BufString[BufString.length () - 1 ] == ' \r ' )) {
85
+ BufString.pop_back ();
86
+ }
87
+ // Handle comments
88
+ if (BufString.find (" #" ) != std::string::npos) {
89
+ BufString.erase (BufString.find (" #" ));
90
+ while ((BufString.length () > 0 ) &&
91
+ (BufString[BufString.length () - 1 ] == ' ' )) {
92
+ BufString.pop_back ();
93
+ }
94
+ }
95
+ // Skip lines with a length = 0 or which don't have "="
96
+ if ((BufString.length () == 0 ) ||
97
+ (BufString.find (" =" ) == std::string::npos)) {
78
98
continue ;
79
99
}
80
- File.getline (Value, sizeof (Value), ' \n ' );
81
-
82
- if (File.fail ()) {
83
- // Fail to process the value while config name is OK. It's likely that
84
- // value is too long. Currently just deal what we have got and ignore
85
- // remaining characters on the line.
86
- // Do we want to restore here? Or just throw an exception?
87
- File.clear (File.rdstate () & ~std::ios_base::failbit);
88
- File.ignore (std::numeric_limits<std::streamsize>::max (), ' \n ' );
100
+ // Finding the position of '='
101
+ Position = BufString.find (" =" );
102
+ // Checking that the variable name is less than MAX_CONFIG_NAME and more
103
+ // than zero character
104
+ if ((Position <= MAX_CONFIG_NAME) && (Position > 0 )) {
105
+ // Checking that the value is less than MAX_CONFIG_VALUE and
106
+ // more than zero character
107
+ if ((BufString.length () - (Position + 1 ) <= MAX_CONFIG_VALUE) &&
108
+ (BufString.length () != Position + 1 )) {
109
+ // Checking for spaces at the beginning and end of the line,
110
+ // before and after '='
111
+ if ((BufString[0 ] == ' ' ) ||
112
+ (BufString[BufString.length () - 1 ] == ' ' ) ||
113
+ (BufString[Position - 1 ] == ' ' ) ||
114
+ (BufString[Position + 1 ] == ' ' )) {
115
+ throw sycl::exception (
116
+ make_error_code (errc::runtime),
117
+ " SPACE found at the beginning/end of the line "
118
+ " or before/after '='" );
119
+ }
120
+ // Creating pairs of (key, value)
121
+ BufString.copy (Key, Position, 0 );
122
+ Key[Position] = ' \0 ' ;
123
+ BufString.copy (Value, BufString.length () - (Position + 1 ),
124
+ Position + 1 );
125
+ Value[BufString.length () - (Position + 1 )] = ' \0 ' ;
126
+ } else {
127
+ throw sycl::exception (
128
+ make_error_code (errc::runtime),
129
+ " The value contains more than " +
130
+ std::to_string (MAX_CONFIG_VALUE) +
131
+ " characters or does not contain them at all" );
132
+ }
133
+ } else {
134
+ throw sycl::exception (make_error_code (errc::runtime),
135
+ " Variable name is more than " +
136
+ std::to_string (MAX_CONFIG_NAME) +
137
+ " or less than one character" );
89
138
}
90
139
91
- // Handle '\r' by nullifying it
92
- const std::streamsize ReadSybmols = File.gcount ();
93
- if (ReadSybmols > 1 && ' \r ' == Value[ReadSybmols - 2 ])
94
- Value[ReadSybmols - 2 ] = ' \0 ' ;
95
-
96
140
initValue (Key, Value);
97
141
}
142
+ File.close ();
98
143
}
99
144
Initialized = true ;
100
145
}
0 commit comments