in Configurator/Core/Ini/IniTemplate.cs [254:438]
public bool ParseConfigurationFile(string templateName)
{
if (_output == null)
{
_output = new Queue();
}
else
{
_output.Clear();
}
bool greatSuccess = false;
try
{
StreamReader reader = null;
if (File.Exists(templateName))
{
reader = new StreamReader(templateName);
}
else
{
var assembly = Assembly.GetExecutingAssembly();
var resources = assembly.GetManifestResourceNames();
Stream stream = assembly.GetManifestResourceStream($"MySql.Configurator.Resources.{templateName}");
reader = new StreamReader(stream);
}
string currentSection = "default";
string currentLine = null;
var deprecatedVariables = DeprecatedVariablesForVersion;
while (!reader.EndOfStream)
{
var previousLine = currentLine;
currentLine = reader.ReadLine();
if (currentLine == null
|| (string.IsNullOrWhiteSpace(currentLine)
&& string.IsNullOrWhiteSpace(previousLine))
|| currentLine.StartsWith("##") // Template comment, do not output.
|| (deprecatedVariables != null
&& deprecatedVariables.Any(dv => currentLine.IndexOf(dv.Name, StringComparison.OrdinalIgnoreCase) >= 0)))
{
continue;
}
// A formula line in the form of
// # [VARIABLE_NAME]="Formula", "Options"
if (currentLine.StartsWith("# ["))
{
ParseFormula(currentLine, reader);
}
else
{
bool processed = false;
// See if we enter a new section in the file. We need that later to translate
// configuration value names to our internal variable names.
Regex section = new Regex(@"\s*\[(?<section>[a-zA-Z]+)]");
Match sectionMatch = section.Match(currentLine);
if (sectionMatch.Success)
{
currentSection = sectionMatch.Groups["section"].Value.ToLowerInvariant();
}
else
{
// Check for simple name=value pairs not associated with a formula and process them.
Regex nameValuePair = new Regex(@"^(?<disabled>[#\s]+)?(?<name>[a-zA-Z_-]+)(\s*)(?:$|=(?<value>.+)?)");
Match match = nameValuePair.Match(currentLine);
if (match.Success)
{
// Process all those settings which can be set through the UI during the configuration
// step. Everything else will just get passed through.
// The list of supported var names might need to be passed in by the UI
string name = match.Groups["name"].Value.ToLowerInvariant();
string variableName = string.Empty;
switch (name)
{
case "enable-named-pipe":
variableName = "SERVER_PIPE";
break;
case "named-pipe-full-access-group":
variableName = "NAMED_PIPE_FULL_ACCESS_GROUP";
break;
case "port":
variableName = currentSection == "client" ? "CLIENT_PORT" : "SERVER_PORT";
break;
case "skip-networking":
variableName = "SERVER_SKIP"; // Only possible with a server section.
break;
case "shared-memory":
variableName = "SHARED_MEMORY";
break;
case "shared-memory-base-name":
variableName = "SHARED_MEMORY_BASE_NAME";
break;
case "socket":
variableName = currentSection == "client" ? "CLIENT_SOCKET" : "SERVER_SOCKET";
break;
}
if (variableName.Length > 0)
{
processed = true;
string value = match.Groups["value"].Value;
var itv = new IniTemplateVariable(currentLine, variableName, value, string.Empty)
{
DefaultValue = value,
Disabled = match.Groups["disabled"].Value.Contains("#"),
OutputParameter = match.Groups["name"].Value
};
switch (variableName)
{
case "SERVER_PORT":
if (itv.DefaultValue != null)
{
Port = uint.Parse(value);
}
itv.Formula = "port";
break;
case "SERVER_SKIP":
EnableNetworking = itv.Disabled;
break;
case "SERVER_SOCKET":
PipeName = itv.DefaultValue;
break;
case "SHARED_MEMORY_BASE_NAME":
MemoryName = itv.DefaultValue;
break;
case "SERVER_PIPE":
EnableNamedPipe = !itv.Disabled;
break;
case "SHARED_MEMORY":
EnableSharedMemory = !itv.Disabled;
break;
case "QUERY_CACHE_SIZE":
EnableQueryCache = !itv.Disabled;
break;
case "QUERY_CACHE_TYPE":
EnableQueryType = !itv.Disabled;
break;
case "NAMED_PIPE_FULL_ACCESS_GROUP":
NamedPipeFullAccessGroup = value;
break;
}
_output.Enqueue(itv);
}
}
}
// Anything else we just pipe through.
if (!processed)
{
_output.Enqueue(new IniTemplateStatic(currentLine));
}
}
}
reader.Close();
reader.Dispose();
greatSuccess = true;
}
catch (Exception ex)
{
_output.Clear();
Logger.LogError(ex.Message);
}
return greatSuccess;
}