// parse a value, either as a number, SuperIO mapping or reflection private bool ParseValue(string value, out int i) { i = 0; value = value.ToLower(); if (TextUtils.IsCNumeric(value)) // parse as number { if (TextUtils.ParseInt(value, out i)) { return(true); } return(false); } if (value.StartsWith("@")) // copy another setting { ConfigParameter item = FindParameterByIdentifier(value.Substring(1)); if (item != null) { i = item.value; return(true); } } // parse as identifier i = SuperIO.IdentifierToIndex(value); if (i == -1) { return(false); } return(true); }
// fill out BinaryFormat struct with data from parameters and class private void PopulateBinaryStruct() { int byte_size = 0; // fill out all non-custom fields FieldInfo[] fieldinfo = Type.GetType(GetType().FullName + "+BinaryFormat").GetFields(BindingFlags.Instance | BindingFlags.Public); if (fieldinfo == null) { throw new Exception("Config " + identifier + " does not have a BinaryFormat struct."); } foreach (FieldInfo field in fieldinfo) { string field_id = field.Name; // mapping array if (field_id == "_mapping") { int count = CountNonZeroParams(); foreach (FieldInfo fi in fieldinfo) { if (fi.Name == "_count") { fi.SetValue(binary_struct, (sbyte)count); } } sbyte[,] map = new sbyte[count, 2]; byte_size += count * 2; count = 0; for (int i = 0; i < configs.Count; i++) { if (configs[i].value != 0) { map[count, 0] = (sbyte)configs[i].index; map[count, 1] = (sbyte)configs[i].value; count++; } } field.SetValue(binary_struct, map); continue; } // config index number if (field_id == "_id") { field.SetValue(binary_struct, Convert.ChangeType(id_number, field.FieldType)); continue; } // unknown custom field if (field_id.StartsWith("_")) { byte_size += Marshal.SizeOf(field.FieldType); continue; } // array fields need to be split into individual numbered parameters if (field.FieldType.IsArray) { Array array = field.GetValue(binary_struct) as Array; for (int i = 0; i < array.Length; i++) { ConfigParameter paramA = FindParameterByIdentifier(field_id + (i + 1).ToString()); if (paramA == null) { throw new Exception("Struct field with no matching parameter (" + field_id + i.ToString() + ")"); } array.SetValue(Convert.ChangeType(paramA.value, field.FieldType.GetElementType()), i); } field.SetValue(binary_struct, array); byte_size += Marshal.SizeOf(field.FieldType.GetElementType()) * array.Length; continue; } // standard field ConfigParameter param = FindParameterByIdentifier(field_id); if (param == null) { throw new Exception("Struct field with no matching parameter (" + field_id + ")"); } field.SetValue(binary_struct, Convert.ChangeType(param.value, field.FieldType)); byte_size += Marshal.SizeOf(field.FieldType); } fieldinfo = Type.GetType(GetType().FullName + "+BinaryFormat").GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo field in fieldinfo) { if (field.Name == "_config_length") { field.SetValue(binary_struct, (UInt16)byte_size); continue; } } }
// parse a single line from config file, returing false on error private static bool ParseLine(string line, int line_num, ref Config cfg, ref List <Config> config_list) { string t = line; // remove comments if (t.Contains(';')) { t = t.Substring(0, t.IndexOf(';')); } if (t.Contains("//")) { t = t.Substring(0, t.IndexOf("//")); } t = t.Trim(); if (t == "") // blank / comment only line { return(true); } t = t.ToLower(); try { // begin a new config if (t.StartsWith("begin")) { if (cfg != null) // missing end { throw new Exception("Unexpected \"begin\" at line " + line_num.ToString()); } string identifier = t.Substring(t.IndexOf(' ')).Trim(); Config new_cfg = FindCfgByIdentifier(identifier); if (new_cfg == null) { throw new Exception("Unknown identifier \"" + identifier + "\" at line " + line_num.ToString()); } cfg = new_cfg; // check for repeats if (cfg.allows_multiple == false) { foreach (Config c in config_list) { if (c.GetType() == cfg.GetType()) { throw new Exception("Multiple configs of type \"" + identifier + "\" not allowed at line " + line_num.ToString()); } } } } // end current config else if (t.StartsWith("end")) { if (cfg == null) { throw new Exception("End without matching begin at line " + line_num.ToString()); } if (t.Length > 3) // must have the config identifier following it or nothing { string identifier = t.Substring(3).Trim(); if (identifier != cfg.identifier.ToLower()) { throw new Exception("End identifier \"" + identifier + "\" does not match previous begin at line " + line_num.ToString()); } } config_list.Add(cfg); cfg = null; } // setting else { if (cfg == null) { throw new Exception("No matching begin for setting at line " + line_num.ToString()); } int eq = t.IndexOf('='); if (eq == -1) { throw new Exception("Missing \"=\" at line " + line_num.ToString()); } string identifier; string value; try { identifier = t.Substring(0, eq - 1).Trim(); value = t.Substring(eq + 1).Trim(); } catch { throw new Exception("Syntax error at line " + line_num.ToString()); } ConfigParameter item = cfg.FindParameterByIdentifier(identifier); if (item == null) { throw new Exception("Unknown identifier \"" + identifier + "\" at line " + line_num.ToString()); } int i; if (!cfg.ParseValue(value, out i)) { throw new Exception("Unable to parse value \"" + value + "\" at line " + line_num.ToString()); } item.value = i; if (Program.opt_verbose) { Console.WriteLine(cfg.identifier + "->" + item.identifier + " = " + item.value.ToString()); } } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(line); return(false); } return(true); }