VR Development Framework
v 1.0.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Events Pages
AVR_SettingsParser.cs
1 using System.Collections;
2 using System.Collections.Generic;
3 using UnityEngine;
4 using System.IO;
5 using System.Text.RegularExpressions;
6 
7 namespace AVR.Core {
8  /// <summary>
9  /// Parser used to parse setting-files.
10  /// </summary>
11  public class AVR_SettingsParser
12  {
13  /// <summary>
14  /// Automatically parse all settingsfiles found that have the *.avr suffix. Duplicate settings are overwritten in alphabetical order of the filename.
15  /// </summary>
16  /// <param name="exclude_overridesettings"> If set to true, any file with the name "~overridesettings.avr" will be excluded. </param>
17  /// <returns> Dictionary of all settings. </returns>
18  public static Dictionary<string, string> AutoParseSettingFiles(bool exclude_overridesettings=false) {
19  string[] files = System.IO.Directory.GetFiles(Application.dataPath+"/..", "*.avr", SearchOption.AllDirectories);
20  System.Array.Sort(files, (a, b) => string.Compare(b, a));
21 
22  Dictionary<string, string> entries = new Dictionary<string, string>();
23  foreach(string file in files) {
24  if(exclude_overridesettings && file.Contains("~overridesettings.avr")) continue;
25  entries = ParseSettings(file, entries);
26  }
27  return entries;
28  }
29 
30  /// <summary>
31  /// Parse a single given settings-file.
32  /// </summary>
33  /// <param name="filepath"> Path of the file in question </param>
34  /// <param name="entries"> pre-existing entries to add to. Duplicates will be overwritten. </param>
35  /// <returns> Dictionary containing all settings from entries as well as the given file. </returns>
36  public static Dictionary<string, string> ParseSettings(string filepath, Dictionary<string, string> entries = null) {
37  AVR.Core.AVR_DevConsole.print("Parsing settingsfile: "+filepath);
38  string content = "";
39  try {
40  content = File.ReadAllText(filepath);
41  } catch(System.Exception) {
42  AVR.Core.AVR_DevConsole.error("Could not open settings file: " + filepath);
43  return entries;
44  }
45 
46  //First we remove all the comments (From hashtag to newline. TODO: Does this even work on Linux/MAC?
47  content = Regex.Replace(content, "#.*(\\r\\n|\\n|\\r)", "");
48 
49  //This regex splits the input at whitespaces, only if they are followed by an even number of quotation marks. See: https://stackoverflow.com/questions/25477562/split-java-string-by-space-and-not-by-double-quotation-that-includes-space
50  List<string> tokens = new List<string>(Regex.Split(content, "(?<!\\G\\S{0,99999}[\"'].{0,99999})\\s|(?<=\\G\\S{0,99999}\".{0,99999}\"\\S{0,99999})\\s|(?<=\\G\\S{0,99999}'.{0,99999}'\\S{0,99999})\\s"));
51 
52  // Clean up: (Delete empty tokens)
53  for(int i=0; i<tokens.Count; i++) {
54  tokens[i] = tokens[i].Trim().Trim('\"');
55  if(tokens[i].Length<1) {
56  tokens.RemoveAt(i);
57  i--;
58  }
59  }
60 
61  // Parse tokens
62  if(entries==null) entries = new Dictionary<string, string>();
63  parseDepth("", 0, tokens, entries);
64 
65  return entries;
66  }
67 
68  // Recusrive parsing function.
69  private static int parseDepth(string context, int i, List<string> content, Dictionary<string, string> entries) {
70  while (i < content.Count)
71  {
72  if (content[i] == "}") return i + 1;
73  // For custom tokens
74  //else if (content[i].equals("$embededCSV") && content[i + 1].equals("="))
75  //{
76  // parseEmbededCSV(context, content[i + 2]);
77  // i += 3;
78  //}
79  //else if (content[i].equals("$embededJSON") && content[i + 1].equals("="))
80  //{
81  // parseEmbededJSON(context, content[i + 2]);
82  // i += 3;
83  //}
84  else if (is_identifier(content[i]) && content[i + 1]=="=" && content[i + 2]=="{")
85  {
86  i = parseDepth(context + "/" + content[i], i + 3, content, entries);
87  }
88  else if (is_identifier(content[i]) && content[i + 1]=="=")
89  { //We dont care if content[i+2] is an identifier, because quotation-strings are also values.
90  entries[context + "/" + content[i]] = content[i + 2];
91  i += 3;
92  }
93  else
94  {
95  AVR.Core.AVR_DevConsole.cerror("Incorrect Token Syntax at (index "+i+"): " + content[i] + " " + content[i + 1] + " " + content[i + 2], "SettingsParser");
96  return int.MaxValue;
97  }
98  }
99  return i;
100  }
101 
102  // Determines if a given token is a valid identifier.
103  private static bool is_identifier(string str)
104  {
105  return Regex.IsMatch(str, "\\w+");
106  }
107  }
108 }
static Dictionary< string, string > AutoParseSettingFiles(bool exclude_overridesettings=false)
Automatically parse all settingsfiles found that have the *.avr suffix. Duplicate settings are overwr...
static int parseDepth(string context, int i, List< string > content, Dictionary< string, string > entries)
static bool is_identifier(string str)
Parser used to parse setting-files.
static Dictionary< string, string > ParseSettings(string filepath, Dictionary< string, string > entries=null)
Parse a single given settings-file.