245 lines
6.0 KiB
C++
245 lines
6.0 KiB
C++
/*
|
|
* Copyright 2015, Axel Dörfler, axeld@pinc-software.de.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
|
|
|
|
#include "SettingsParser.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <DriverSettingsMessageAdapter.h>
|
|
|
|
|
|
class AbstractArgsConverter : public DriverSettingsConverter {
|
|
public:
|
|
status_t ConvertEmptyFromDriverSettings(
|
|
const driver_parameter& parameter, const char* name, uint32 type,
|
|
BMessage& target)
|
|
{
|
|
if (parameter.parameter_count != 0 || strcmp(name, Name()) == 0)
|
|
return B_OK;
|
|
|
|
BMessage message;
|
|
return target.AddMessage(name, &message);
|
|
}
|
|
|
|
protected:
|
|
status_t AddSubMessage(const driver_parameter& parameter, int32 index,
|
|
BMessage& target)
|
|
{
|
|
const char* condition = parameter.values[index];
|
|
BMessage args;
|
|
for (index++; index < parameter.value_count; index++) {
|
|
status_t status = args.AddString("args",
|
|
parameter.values[index]);
|
|
if (status != B_OK)
|
|
return status;
|
|
}
|
|
return target.AddMessage(condition, &args);
|
|
}
|
|
|
|
virtual const char* Name() = 0;
|
|
};
|
|
|
|
|
|
class ConditionConverter : public AbstractArgsConverter {
|
|
public:
|
|
status_t ConvertFromDriverSettings(const driver_parameter& parameter,
|
|
const char* name, int32 index, uint32 type, BMessage& target)
|
|
{
|
|
BMessage message;
|
|
if (strcmp(parameter.name, "if") == 0) {
|
|
// Parse values directly following "if", with special
|
|
// handling for the "not" operator.
|
|
if (index != 0)
|
|
return B_OK;
|
|
|
|
BMessage* add = ⌖
|
|
bool notOperator = parameter.value_count > 1
|
|
&& strcmp(parameter.values[0], "not") == 0;
|
|
if (notOperator) {
|
|
add = &message;
|
|
index++;
|
|
}
|
|
|
|
status_t status = AddSubMessage(parameter, index, *add);
|
|
if (status == B_OK && notOperator)
|
|
status = target.AddMessage("not", &message);
|
|
|
|
return status;
|
|
}
|
|
if (strcmp(parameter.name, "not") == 0) {
|
|
if (index != 0)
|
|
return B_OK;
|
|
|
|
return AddSubMessage(parameter, index, target);
|
|
}
|
|
|
|
message.AddString("args", parameter.values[index]);
|
|
return target.AddMessage(parameter.name, &message);
|
|
}
|
|
|
|
const char* Name()
|
|
{
|
|
return "if";
|
|
}
|
|
};
|
|
|
|
|
|
class EventConverter : public AbstractArgsConverter {
|
|
public:
|
|
status_t ConvertFromDriverSettings(const driver_parameter& parameter,
|
|
const char* name, int32 index, uint32 type, BMessage& target)
|
|
{
|
|
BMessage message;
|
|
if (strcmp(parameter.name, "on") == 0) {
|
|
// Parse values directly following "on"
|
|
if (index != 0)
|
|
return B_OK;
|
|
|
|
return AddSubMessage(parameter, index, target);
|
|
}
|
|
|
|
message.AddString("args", parameter.values[index]);
|
|
return target.AddMessage(parameter.name, &message);
|
|
}
|
|
|
|
const char* Name()
|
|
{
|
|
return "on";
|
|
}
|
|
};
|
|
|
|
|
|
class RunConverter : public DriverSettingsConverter {
|
|
public:
|
|
status_t ConvertFromDriverSettings(const driver_parameter& parameter,
|
|
const char* name, int32 index, uint32 type, BMessage& target)
|
|
{
|
|
if (parameter.parameter_count == 0)
|
|
return target.AddString("target", parameter.values[index]);
|
|
|
|
return B_NOT_SUPPORTED;
|
|
}
|
|
|
|
status_t ConvertEmptyFromDriverSettings(
|
|
const driver_parameter& parameter, const char* name, uint32 type,
|
|
BMessage& target)
|
|
{
|
|
if (parameter.parameter_count != 0)
|
|
return B_OK;
|
|
|
|
return target.AddString("target", name);
|
|
}
|
|
};
|
|
|
|
|
|
const static settings_template kConditionTemplate[] = {
|
|
{B_STRING_TYPE, NULL, NULL, true, new ConditionConverter()},
|
|
{B_MESSAGE_TYPE, "not", kConditionTemplate},
|
|
{B_MESSAGE_TYPE, "and", kConditionTemplate},
|
|
{B_MESSAGE_TYPE, "or", kConditionTemplate},
|
|
{0, NULL, NULL}
|
|
};
|
|
|
|
const static settings_template kEventTemplate[] = {
|
|
{B_STRING_TYPE, NULL, NULL, true, new EventConverter()},
|
|
{B_MESSAGE_TYPE, "and", kEventTemplate},
|
|
{B_MESSAGE_TYPE, "or", kEventTemplate},
|
|
{0, NULL, NULL}
|
|
};
|
|
|
|
const static settings_template kPortTemplate[] = {
|
|
{B_STRING_TYPE, "name", NULL, true},
|
|
{B_INT32_TYPE, "capacity", NULL},
|
|
};
|
|
|
|
const static settings_template kEnvTemplate[] = {
|
|
{B_STRING_TYPE, "from_script", NULL, true},
|
|
{B_STRING_TYPE, NULL, NULL},
|
|
};
|
|
|
|
const static settings_template kJobTemplate[] = {
|
|
{B_STRING_TYPE, "name", NULL, true},
|
|
{B_BOOL_TYPE, "disabled", NULL},
|
|
{B_STRING_TYPE, "launch", NULL},
|
|
{B_STRING_TYPE, "requires", NULL},
|
|
{B_BOOL_TYPE, "legacy", NULL},
|
|
{B_MESSAGE_TYPE, "port", kPortTemplate},
|
|
{B_MESSAGE_TYPE, "on", kEventTemplate},
|
|
{B_MESSAGE_TYPE, "if", kConditionTemplate},
|
|
{B_BOOL_TYPE, "no_safemode", NULL},
|
|
{B_BOOL_TYPE, "on_demand", NULL},
|
|
{B_MESSAGE_TYPE, "env", kEnvTemplate},
|
|
{0, NULL, NULL}
|
|
};
|
|
|
|
const static settings_template kTargetTemplate[] = {
|
|
{B_STRING_TYPE, "name", NULL, true},
|
|
{B_BOOL_TYPE, "reset", NULL},
|
|
{B_MESSAGE_TYPE, "on", kEventTemplate},
|
|
{B_MESSAGE_TYPE, "if", kConditionTemplate},
|
|
{B_BOOL_TYPE, "no_safemode", NULL},
|
|
{B_MESSAGE_TYPE, "env", kEnvTemplate},
|
|
{B_MESSAGE_TYPE, "job", kJobTemplate},
|
|
{B_MESSAGE_TYPE, "service", kJobTemplate},
|
|
{0, NULL, NULL}
|
|
};
|
|
|
|
const static settings_template kRunConditionalTemplate[] = {
|
|
{B_STRING_TYPE, NULL, NULL, true, new RunConverter()},
|
|
{0, NULL, NULL}
|
|
};
|
|
|
|
const static settings_template kRunTemplate[] = {
|
|
{B_STRING_TYPE, NULL, NULL, true, new RunConverter()},
|
|
{B_MESSAGE_TYPE, "if", kConditionTemplate},
|
|
{B_MESSAGE_TYPE, "then", kRunConditionalTemplate},
|
|
{B_MESSAGE_TYPE, "else", kRunConditionalTemplate},
|
|
{0, NULL, NULL}
|
|
};
|
|
|
|
const static settings_template kSettingsTemplate[] = {
|
|
{B_MESSAGE_TYPE, "target", kTargetTemplate},
|
|
{B_MESSAGE_TYPE, "job", kJobTemplate},
|
|
{B_MESSAGE_TYPE, "service", kJobTemplate},
|
|
{B_MESSAGE_TYPE, "run", kRunTemplate},
|
|
{0, NULL, NULL}
|
|
};
|
|
|
|
|
|
SettingsParser::SettingsParser()
|
|
{
|
|
}
|
|
|
|
|
|
status_t
|
|
SettingsParser::ParseFile(const char* path, BMessage& settings)
|
|
{
|
|
DriverSettingsMessageAdapter adapter;
|
|
return adapter.ConvertFromDriverSettings(path, kSettingsTemplate, settings);
|
|
}
|
|
|
|
|
|
#ifdef TEST_HAIKU
|
|
|
|
|
|
status_t
|
|
SettingsParser::Parse(const char* text, BMessage& settings)
|
|
{
|
|
void* driverSettings = parse_driver_settings_string(text);
|
|
if (driverSettings == NULL)
|
|
return B_BAD_VALUE;
|
|
|
|
DriverSettingsMessageAdapter adapter;
|
|
status_t status = adapter.ConvertFromDriverSettings(
|
|
*get_driver_settings(driverSettings), kSettingsTemplate, settings);
|
|
|
|
delete_driver_settings(driverSettings);
|
|
return status;
|
|
}
|
|
|
|
|
|
#endif // TEST_HAIKU
|