Skip to content

Commit 49358e7

Browse files
committed
Fix literalEval() to parse Python-style dicts and lists
- Replace empty HashMap return with actual parser - Handle dict format: {'key': value} - Handle list format: [val1, val2] - Fix read(), initVal(), defaultMaxTime() to use parser Fixes #197
1 parent f21bb89 commit 49358e7

1 file changed

Lines changed: 177 additions & 11 deletions

File tree

concoredocker.java

Lines changed: 177 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,13 @@ private static Map<String, Object> parseFile(String filename) throws IOException
5858

5959
private static void defaultMaxTime(int defaultValue) {
6060
try {
61-
String content = new String(Files.readAllBytes(Paths.get(inpath + "1/concore.maxtime")));
62-
maxtime = literalEval(content).size();
61+
String content = new String(Files.readAllBytes(Paths.get(inpath + "1/concore.maxtime"))).trim();
62+
Object val = parsePythonLiteral(content);
63+
if (val instanceof Number) {
64+
maxtime = ((Number) val).intValue();
65+
} else {
66+
maxtime = defaultValue;
67+
}
6368
} catch (IOException e) {
6469
maxtime = defaultValue;
6570
}
@@ -90,9 +95,16 @@ private static Object read(int port, String name, String initstr) {
9095
retrycount++;
9196
}
9297
s += ins;
93-
Object[] inval = new Map[] { literalEval(ins) };
94-
int simtime = Math.max((int) inval[0], 0); // assuming simtime is an integer
95-
return inval[1];
98+
Object[] inval = literalEvalList(ins);
99+
if (inval.length > 0) {
100+
int simtime = ((Number) inval[0]).intValue();
101+
if (inval.length > 1) {
102+
Object[] result = new Object[inval.length - 1];
103+
System.arraycopy(inval, 1, result, 0, result.length);
104+
return result;
105+
}
106+
}
107+
return initstr;
96108
} catch (IOException | InterruptedException e) {
97109
return initstr;
98110
}
@@ -129,21 +141,175 @@ private static void write(int port, String name, Object val, int delta) {
129141
}
130142

131143
private static Object[] initVal(String simtimeVal) {
132-
int simtime = 0;
133144
Object[] val = new Object[] {};
134145
try {
135-
Object[] arrayVal = new Map[] { literalEval(simtimeVal) };
136-
simtime = (int) arrayVal[0]; // assuming simtime is an integer
137-
val = new Object[arrayVal.length - 1];
138-
System.arraycopy(arrayVal, 1, val, 0, val.length);
146+
Object[] arrayVal = literalEvalList(simtimeVal);
147+
if (arrayVal.length > 1) {
148+
val = new Object[arrayVal.length - 1];
149+
System.arraycopy(arrayVal, 1, val, 0, val.length);
150+
}
139151
} catch (Exception e) {
140152
e.printStackTrace();
141153
}
142154
return val;
143155
}
144156

145157
private static Map<String, Object> literalEval(String s) {
146-
158+
Object result = parsePythonLiteral(s);
159+
if (result instanceof Map) {
160+
return (Map<String, Object>) result;
161+
}
147162
return new HashMap<>();
148163
}
164+
165+
private static Object[] literalEvalList(String s) {
166+
Object result = parsePythonLiteral(s);
167+
if (result instanceof Object[]) {
168+
return (Object[]) result;
169+
}
170+
return new Object[]{};
171+
}
172+
173+
private static Object parsePythonLiteral(String s) {
174+
if (s == null) return null;
175+
s = s.trim();
176+
if (s.isEmpty()) return null;
177+
178+
// dict: {'key': value, ...}
179+
if (s.startsWith("{") && s.endsWith("}")) {
180+
return parseDict(s.substring(1, s.length() - 1));
181+
}
182+
// list: [val1, val2, ...]
183+
if (s.startsWith("[") && s.endsWith("]")) {
184+
return parseList(s.substring(1, s.length() - 1));
185+
}
186+
// single value
187+
return parseValue(s);
188+
}
189+
190+
private static Map<String, Object> parseDict(String inner) {
191+
Map<String, Object> map = new HashMap<>();
192+
if (inner.trim().isEmpty()) return map;
193+
194+
int i = 0;
195+
while (i < inner.length()) {
196+
// skip whitespace
197+
while (i < inner.length() && Character.isWhitespace(inner.charAt(i))) i++;
198+
if (i >= inner.length()) break;
199+
200+
// parse key (quoted string)
201+
char quote = inner.charAt(i);
202+
if (quote != '\'' && quote != '"') break;
203+
i++;
204+
int keyStart = i;
205+
while (i < inner.length() && inner.charAt(i) != quote) i++;
206+
String key = inner.substring(keyStart, i);
207+
i++; // skip closing quote
208+
209+
// skip to colon
210+
while (i < inner.length() && inner.charAt(i) != ':') i++;
211+
i++; // skip colon
212+
213+
// skip whitespace
214+
while (i < inner.length() && Character.isWhitespace(inner.charAt(i))) i++;
215+
216+
// parse value
217+
int[] endIdx = new int[]{i};
218+
Object val = parseValueAt(inner, endIdx);
219+
i = endIdx[0];
220+
map.put(key, val);
221+
222+
// skip to comma or end
223+
while (i < inner.length() && inner.charAt(i) != ',') i++;
224+
i++; // skip comma
225+
}
226+
return map;
227+
}
228+
229+
private static Object[] parseList(String inner) {
230+
if (inner.trim().isEmpty()) return new Object[]{};
231+
232+
java.util.List<Object> list = new java.util.ArrayList<>();
233+
int i = 0;
234+
while (i < inner.length()) {
235+
while (i < inner.length() && Character.isWhitespace(inner.charAt(i))) i++;
236+
if (i >= inner.length()) break;
237+
238+
int[] endIdx = new int[]{i};
239+
Object val = parseValueAt(inner, endIdx);
240+
i = endIdx[0];
241+
list.add(val);
242+
243+
while (i < inner.length() && (Character.isWhitespace(inner.charAt(i)) || inner.charAt(i) == ',')) i++;
244+
}
245+
return list.toArray();
246+
}
247+
248+
private static Object parseValueAt(String s, int[] idx) {
249+
int i = idx[0];
250+
while (i < s.length() && Character.isWhitespace(s.charAt(i))) i++;
251+
if (i >= s.length()) {
252+
idx[0] = i;
253+
return null;
254+
}
255+
256+
char c = s.charAt(i);
257+
// nested dict
258+
if (c == '{') {
259+
int depth = 1, start = i;
260+
i++;
261+
while (i < s.length() && depth > 0) {
262+
if (s.charAt(i) == '{') depth++;
263+
else if (s.charAt(i) == '}') depth--;
264+
i++;
265+
}
266+
idx[0] = i;
267+
return parsePythonLiteral(s.substring(start, i));
268+
}
269+
// nested list
270+
if (c == '[') {
271+
int depth = 1, start = i;
272+
i++;
273+
while (i < s.length() && depth > 0) {
274+
if (s.charAt(i) == '[') depth++;
275+
else if (s.charAt(i) == ']') depth--;
276+
i++;
277+
}
278+
idx[0] = i;
279+
return parsePythonLiteral(s.substring(start, i));
280+
}
281+
// quoted string
282+
if (c == '\'' || c == '"') {
283+
char quote = c;
284+
i++;
285+
int start = i;
286+
while (i < s.length() && s.charAt(i) != quote) i++;
287+
String val = s.substring(start, i);
288+
i++; // skip closing quote
289+
idx[0] = i;
290+
return val;
291+
}
292+
// number or other
293+
int start = i;
294+
while (i < s.length() && s.charAt(i) != ',' && s.charAt(i) != '}' && s.charAt(i) != ']' && !Character.isWhitespace(s.charAt(i))) {
295+
i++;
296+
}
297+
idx[0] = i;
298+
return parseValue(s.substring(start, i));
299+
}
300+
301+
private static Object parseValue(String s) {
302+
s = s.trim();
303+
if (s.isEmpty()) return null;
304+
if (s.equals("None") || s.equals("null")) return null;
305+
if (s.equals("True") || s.equals("true")) return true;
306+
if (s.equals("False") || s.equals("false")) return false;
307+
try {
308+
if (s.contains(".")) return Double.parseDouble(s);
309+
return Integer.parseInt(s);
310+
} catch (NumberFormatException e) {
311+
return s;
312+
}
313+
}
149314
}
315+

0 commit comments

Comments
 (0)