From 48b5cee19cf8e969572199a248d00b5ba82050de Mon Sep 17 00:00:00 2001 From: erdgeist Date: Fri, 12 Aug 2016 22:35:55 +0200 Subject: Tidy up config parser --- config.c | 529 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 284 insertions(+), 245 deletions(-) (limited to 'config.c') diff --git a/config.c b/config.c index 8465dc7..663f038 100644 --- a/config.c +++ b/config.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -32,6 +31,94 @@ static char *midi_note[] = { "C9", "C#9", "D9", "D#9", "E9", "F9", "F#9", "G9", "G#9", "A9", "A#9", "B9" }; +enum { + KEYWORD_STRINGS, + KEYWORD_STRING, + KEYWORD_LINE, + KEYWORD_MODE, + KEYWORD_MODE_ONE_OCTAVE, + KEYWORD_MODE_TWO_OCTAVES, + KEYWORD_MODE_THREE_OCTAVES, + KEYWORD_MODE_CONTROL, + KEYWORD_MODE_CONTROL_INVERSE, + KEYWORD_CHANNEL, + KEYWORD_NOTE, + KEYWORD_AFTERTOUCH, + KEYWORD_NONE, + KEYWORD_PITCH_BEND_UP, + KEYWORD_PITCH_BEND_DOWN, + KEYWORD_MIDI_CONTROL, + KEYWORD_MIDI_CONTROL_INVERSE, + KEYWORD_CONTROLLER, + KEYWORD_TIMETOSILENCE, + KEYWORD_TWOOCTAVESPLIT, + KEYWORD_THREEOCTAVESPLIT_1, + KEYWORD_THREEOCTAVESPLIT_2, + KEYWORD_MIDI_MAIN_CONTROL, + KEYWORD_MIDI_MAIN_CHANNEL +}; + +typedef struct { + int id; + char *name; +} keyword; + +static keyword keywords[] = { + { KEYWORD_STRINGS, "Strings" }, + { KEYWORD_STRING, "String" }, + { KEYWORD_LINE, "Line" }, + { KEYWORD_MODE, "Mode" }, + { KEYWORD_MODE_ONE_OCTAVE, "midi_one_octave" }, + { KEYWORD_MODE_TWO_OCTAVES, "midi_two_octaves" }, + { KEYWORD_MODE_THREE_OCTAVES, "midi_three_octaves" }, + { KEYWORD_MODE_CONTROL, "midi_control" }, + { KEYWORD_MODE_CONTROL_INVERSE, "midi_control_inverse" }, + { KEYWORD_CHANNEL, "Channel" }, + { KEYWORD_NOTE, "Note" }, + { KEYWORD_AFTERTOUCH, "AfterTouch" }, + { KEYWORD_NONE, "none" }, + { KEYWORD_PITCH_BEND_UP, "pitch_bend_up" }, + { KEYWORD_PITCH_BEND_DOWN, "pitch_bend_down" }, + { KEYWORD_MIDI_CONTROL, "midi_control" }, + { KEYWORD_MIDI_CONTROL_INVERSE, "midi_control_inverse" }, + { KEYWORD_CONTROLLER, "Controller" }, + { KEYWORD_TIMETOSILENCE, "TimeToSilence" }, + { KEYWORD_TWOOCTAVESPLIT, "midi_two_octave_split" }, + { KEYWORD_THREEOCTAVESPLIT_1, "midi_three_octave_split_1" }, + { KEYWORD_THREEOCTAVESPLIT_2, "midi_three_octave_split_2" }, + { KEYWORD_MIDI_MAIN_CONTROL, "midi_main_control" }, + { KEYWORD_MIDI_MAIN_CHANNEL, "midi_main_channel" }, + { -1, 0 } +}; + +static int g_current_string; + +static int +config_findkeyword(char **line) +{ + char *_l = *line; + int i; + + while (isspace(*_l)) + ++_l; + + for (i=0; keywords[i].name; ++i) { + size_t kl = strlen(keywords[i].name); + if (!strncasecmp(_l, keywords[i].name, kl)) { + if (!isspace(_l[kl]) && _l[kl]) + continue; + _l += strlen(keywords[i].name); + + /* Skip rest of white spaces */ + while (isspace(*_l)) + ++_l; + *line = _l; + return keywords[i].id; + } + } + return -1; +} + static uint8_t config_midi_note_from_string(char *string) { @@ -43,263 +130,215 @@ config_midi_note_from_string(char *string) return 0xff; } -char *config_midi_note_to_string(int string) { +char * +config_midi_note_to_string(int string) +{ return midi_note[string]; } -#define LINEBUFFER 512 -static char *config_file; -void -config_parse(char *config_file_in) +int +config_handle_line(char *line) { - FILE *fh; - char line_in[LINEBUFFER]; - int current_string = -1; + StringConfig *sc = g_string_conf + g_current_string; + int split_done = 0; + char *_line = line; - if (!config_file_in && !config_file) - return; - if (config_file_in) - config_file = config_file_in; - fh = fopen(config_file, "r"); - - if (!fh) { - fprintf(stderr, "Couldn't open config file %s, exiting.\n", config_file); - exit(1); - } - - //Reinitialise string config array - memset(g_string_conf, 0, sizeof(g_string_conf)); - g_max_y = 1024; + //Skip leading spaces + while (isspace(*line)) + ++line; + if (*line == 0 || *line == '#' || *line == '\n') + return 0; - while (!feof(fh)) { - char *line = fgets(line_in, LINEBUFFER, fh); + switch (config_findkeyword(&line)) { + case KEYWORD_STRINGS: + g_string_count = atol(line); + if (!g_string_count || g_string_count > MAX_LINECOUNT) { + fprintf(stderr, "Incorrect number of strings: %s\n", _line); + return -1; + } + printf("GLOBAL: Configuring expected lines %d\n", g_string_count); + break; + case KEYWORD_STRING: + g_current_string = atol(line) - 1; + printf("Switching to string: %d\n", g_current_string + 1); + if (g_current_string < 0 || g_current_string > g_string_count) { + fprintf(stderr, "Incorrect string selected: %s\n", _line); + return -1; + } + break; + case KEYWORD_LINE: + { + LLine *l = &sc->line; + if (sscanf(line, "%d %d %d %d", &l->x0, &l->y0, &l->x1, &l->y1) != 4) { + fprintf(stderr, "Incorrect Line statement for string\n"); + return -1; + } + if (l->y0 > l->y1) { + l->y0 ^= l->y1; + l->y1 ^= l->y0; + l->y0 ^= l->y1; + l->x0 ^= l->x1; + l->x1 ^= l->x0; + l->x0 ^= l->x1; - if (!line) + } + if (l->y0 > g_min_y) + g_min_y = l->y0; + if (l->y1 < g_max_y) + g_max_y = l->y1; + break; + } + case KEYWORD_MODE: + switch (config_findkeyword(&line)) { + case KEYWORD_MODE_ONE_OCTAVE: + sc->mode = midi_one_octave; + printf("String %d is midi_one_octave\n", 1 + g_current_string); break; + case KEYWORD_MODE_TWO_OCTAVES: + sc->mode = midi_two_octaves; + printf("String %d is midi_two_octaves\n", 1 + g_current_string); + break; + case KEYWORD_MODE_THREE_OCTAVES: + sc->mode = midi_three_octaves; + printf("String %d is midi_three_octaves\n", 1 + g_current_string); + break; + case KEYWORD_MODE_CONTROL: + sc->mode = midi_control; + printf("String %d is midi_control\n", 1 + g_current_string); + break; + case KEYWORD_MODE_CONTROL_INVERSE: + sc->mode = midi_control_inv; + printf("String %d is midi_control_inverse\n", 1 + g_current_string); + break; + default: + fprintf(stderr, "Illegal Mode for string: %s\n", _line); + return -1; - //Skip leading spaces - while (isspace(*line)) - ++line; - if (*line == 0 || *line == '#' || *line == '\n') - continue; - - if (!strncasecmp(line, "Strings", 7) && isspace(line[7])) { - line += 7; - while (isspace(*line)) - ++line; - g_string_count = atol(line); - if (!g_string_count || g_string_count > MAX_LINECOUNT) { - fprintf(stderr, "Incorrect number of strings: %s\n", line); - exit(1); - } - printf("GLOBAL: Configuring expected lines %d\n", g_string_count); - } else if (!strncasecmp(line, "String", 6) && isspace(line[6])) { - line += 6; - while (isspace(*line)) - ++line; - current_string = atol(line); - printf("Switching to string: %d\n", current_string); - if (current_string < 0 || current_string > g_string_count) { - fprintf(stderr, "Incorrect string selected: %s\n", line); - exit(1); - } - } else if (!strncasecmp(line, "Line", 4) && isspace(line[4])) { - LLine *l = &g_string_conf[current_string - 1].line; - - if (current_string == -1) { - fprintf(stderr, "No string selected yet.\n"); - exit(1); - } - line += 4; - while (isspace(*line)) - ++line; - if (sscanf(line, "%d %d %d %d", &l->x0, &l->y0, &l->x1, &l->y1) != 4) { - fprintf(stderr, "Incorrect Line statement for string\n"); - exit(1); - } - if (l->y0 > l->y1) { - l->y0 ^= l->y1; - l->y1 ^= l->y0; - l->y0 ^= l->y1; - l->x0 ^= l->x1; - l->x1 ^= l->x0; - l->x0 ^= l->x1; - - } - if (l->y0 > g_min_y) - g_min_y = l->y0; - if (l->y1 < g_max_y) - g_max_y = l->y1; - } else if (!strncasecmp(line, "Mode", 4) && isspace(line[4])) { - if (current_string == -1) { - fprintf(stderr, "No string selected yet.\n"); - exit(1); - } - line += 4; - while (isspace(*line)) - ++line; - if (!strncasecmp(line, "midi_one_octave", 15) && (!line[15] || isspace(line[15]))) { - g_string_conf[current_string - 1].mode = midi_one_octave; - printf("String %d is midi_one_octave\n", current_string); - } else if (!strncasecmp(line, "midi_two_octaves", 16) && (!line[16] || isspace(line[16]))) { - g_string_conf[current_string - 1].mode = midi_two_octaves; - printf("String %d is midi_two_octaves\n", current_string); - } else if (!strncasecmp(line, "midi_three_octaves", 18) && (!line[18] || isspace(line[18]))) { - g_string_conf[current_string - 1].mode = midi_three_octaves; - printf("String %d is midi_three_octaves\n", current_string); - } else if (!strncasecmp(line, "midi_control", 12) && (!line[12] || isspace(line[12]))) { - g_string_conf[current_string - 1].mode = midi_control; - printf("String %d is midi_control\n", current_string); - } else if (!strncasecmp(line, "midi_control_inverse", 20) && (!line[20] || isspace(line[20]))) { - g_string_conf[current_string - 1].mode = midi_control_inv; - printf("String %d is midi_control_inverse\n", current_string); - } else { - fprintf(stderr, "Illegal Mode for string: %s\n", line); - exit(1); - } - } else if (!strncasecmp(line, "Channel", 7) && isspace(line[7])) { - if (current_string == -1) { - fprintf(stderr, "No string selected yet.\n"); - exit(1); - } - line += 7; - while (isspace(*line)) - ++line; - g_string_conf[current_string - 1].channel = atol(line); - if (g_string_conf[current_string - 1].channel > 16) { - fprintf(stderr, "Incorrect channel specified: %s.\n", line); - exit(1); - } - printf("String %d is on channel %d\n", current_string, g_string_conf[current_string - 1].channel); - } else if (!strncasecmp(line, "Note", 4) && isspace(line[4])) { - if (current_string == -1) { - fprintf(stderr, "No string selected yet.\n"); - exit(1); - } - line += 4; - while (isspace(*line)) - ++line; - g_string_conf[current_string - 1].note = config_midi_note_from_string(line); - if (g_string_conf[current_string - 1].note == 0xff) { - fprintf(stderr, "Unknown midi note specified: %s.\n", line); - exit(1); - } - printf("String %d is midi note %d\n", current_string, g_string_conf[current_string - 1].note); - } else if (!strncasecmp(line, "AfterTouch", 10) && isspace(line[10])) { - if (current_string == -1) { - fprintf(stderr, "No string selected yet.\n"); - exit(1); - } - line += 10; - while (isspace(*line)) - ++line; - if (!strncasecmp(line, "none", 4) && (!line[4] || isspace(line[4]))) { - g_string_conf[current_string - 1].modifier = none; - printf("String %d does not act aftertouch\n", current_string); - } else if (!strncasecmp(line, "pitch_bend_up", 13) && (!line[13] || isspace(line[13]))) { - g_string_conf[current_string - 1].modifier = pitch_bend_up; - printf("String %d acts aftertouch as pitch_bend_up\n", current_string); - } else if (!strncasecmp(line, "pitch_bend_down", 15) && (!line[15] || isspace(line[15]))) { - g_string_conf[current_string - 1].modifier = pitch_bend_down; - printf("String %d acts aftertouch as pitch_bend_down\n", current_string); - } else if (!strncasecmp(line, "midi_control", 12) && (!line[12] || isspace(line[12]))) { - g_string_conf[current_string - 1].modifier = midi_controller; - printf("String %d acts aftertouch as midi_controller\n", current_string); - } else if (!strncasecmp(line, "midi_control_inverse", 20) && (!line[20] || isspace(line[20]))) { - g_string_conf[current_string - 1].modifier = midi_controller_inv; - printf("String %d acts aftertouch as midi_controller_inverse\n", current_string); - } else { - fprintf(stderr, "Illegal Modifier for string: %s\n", line); - exit(1); - } - } else if (!strncasecmp(line, "Controller", 10) && isspace(line[10])) { - if (current_string == -1) { - fprintf(stderr, "No string selected yet.\n"); - exit(1); - } - line += 10; - while (isspace(*line)) - ++line; - g_string_conf[current_string - 1].controller = atol(line); - printf("String %d is on midi_controller line %d\n", current_string, g_string_conf[current_string - 1].controller); - } else if (!strncasecmp(line, "TimeToSilence", 13) && isspace(line[13])) { - if (current_string == -1) { - fprintf(stderr, "No string selected yet.\n"); - exit(1); - } - line += 13; - while (isspace(*line)) - ++line; - g_string_conf[current_string - 1].timetosilence = atol(line); - printf("String %d has a timetosilence of %d\n", current_string, g_string_conf[current_string - 1].timetosilence); - } else if (!strncasecmp(line, "midi_two_octave_split", 21) && isspace(line[21])) { - line += 21; - while (isspace(*line)) - ++line; - g_midi_two_octave_split = atol(line); - printf("Splitting TWO octaves at %d%%\n", g_midi_two_octave_split); - if (g_midi_two_octave_split < 0 || g_midi_two_octave_split > 100) { - fprintf(stderr, "Invalid percentage in line: %s\n", line); - exit(1); - } - g_midi_two_octave_split = (256 * g_midi_two_octave_split) / 100; - } else if (!strncasecmp(line, "midi_three_octave_split_1", 25) && isspace(line[25])) { - line += 25; - while (isspace(*line)) - ++line; - g_midi_three_octave_split_1 = atol(line); - printf("Splitting THREE octaves top above %d%%\n", g_midi_three_octave_split_1); - if (g_midi_three_octave_split_1 < 0 || g_midi_three_octave_split_1 > 100) { - fprintf(stderr, "Invalid percentage in line: %s\n", line); - exit(1); - } - g_midi_three_octave_split_1 = (256 * g_midi_three_octave_split_1) / 100; - } else if (!strncasecmp(line, "midi_three_octave_split_2", 25) && isspace(line[25])) { - line += 25; - while (isspace(*line)) - ++line; - g_midi_three_octave_split_2 = atol(line); - printf("Splitting THREE octaves bottom below %d%%\n", g_midi_three_octave_split_2); - if (g_midi_three_octave_split_2 < 0 || g_midi_three_octave_split_2 > 100) { - fprintf(stderr, "Invalid percentage in line: %s\n", line); - exit(1); - } - g_midi_three_octave_split_2 = (256 * g_midi_three_octave_split_2) / 100; - } else if (!strncasecmp(line, "midi_main_control", 17) && isspace(line[17])) { - line += 17; - while (isspace(*line)) - ++line; - g_midi_main_control = atol(line); - printf("All Strings modify controller %d\n", g_midi_main_control); - if (g_midi_main_control > 127) { - fprintf(stderr, "Invalid controller number %d in line: %s\n", g_midi_main_control, line); - exit(1); - } - } else if (!strncasecmp(line, "midi_main_channel", 17) && isspace(line[17])) { - line += 17; - while (isspace(*line)) - ++line; - g_midi_main_channel = atol(line); - printf("All Strings modify controller %d on channel %d\n", g_midi_main_control, g_midi_main_channel); - if (g_midi_main_channel < 1 || g_midi_main_channel > 16) { - fprintf(stderr, "Invalid channel number %d in line: %s\n", g_midi_main_channel, line); - exit(1); - } - } else { - fprintf(stderr, "Unhandled config line: %s\n", line); + } + break; + case KEYWORD_CHANNEL: + sc->channel = atol(line); + if (sc->channel > 16) { + fprintf(stderr, "Incorrect channel specified: %s.\n", _line); + return -1; + } + printf("String %d is on channel %d\n", g_current_string, sc->channel); + break; + case KEYWORD_NOTE: + sc->note = config_midi_note_from_string(line); + if (sc->note == 0xff) { + fprintf(stderr, "Unknown midi note specified: %s.\n", _line); + return -1; + } + printf("String %d is midi note %d\n", g_current_string, sc->note); + break; + case KEYWORD_AFTERTOUCH: + switch (config_findkeyword(&line)) { + case KEYWORD_NONE: + sc->modifier = none; + printf("String %d does not act aftertouch\n", 1 + g_current_string); + break; + case KEYWORD_PITCH_BEND_UP: + sc->modifier = pitch_bend_up; + printf("String %d acts aftertouch as pitch_bend_up\n", 1 + g_current_string); + break; + case KEYWORD_PITCH_BEND_DOWN: + sc->modifier = pitch_bend_down; + printf("String %d acts aftertouch as pitch_bend_down\n", 1 + g_current_string); + break; + case KEYWORD_MIDI_CONTROL: + sc->modifier = midi_controller; + printf("String %d acts aftertouch as midi_controller\n", 1 + g_current_string); + break; + case KEYWORD_MIDI_CONTROL_INVERSE: + sc->modifier = midi_controller_inv; + printf("String %d acts aftertouch as midi_controller_inverse\n", 1 + g_current_string); + break; + default: + fprintf(stderr, "Illegal Modifier for string: %s\n", _line); + return -1; + } + break; + case KEYWORD_CONTROLLER: + sc->controller = atol(line); + printf("String %d is on midi_controller line %d\n", 1 + g_current_string, sc->controller); + break; + case KEYWORD_TIMETOSILENCE: + sc->timetosilence = atol(line); + printf("String %d has a timetosilence of %d\n", 1 + g_current_string, sc->timetosilence); + break; + case KEYWORD_TWOOCTAVESPLIT: + g_midi_two_octave_split = atol(line); + printf("Splitting TWO octaves at %d%%\n", g_midi_two_octave_split); + if (g_midi_two_octave_split < 0 || g_midi_two_octave_split > 100) { + fprintf(stderr, "Invalid percentage in line: %s\n", _line); exit(1); } + g_midi_two_octave_split = (256 * g_midi_two_octave_split) / 100; + break; + case KEYWORD_THREEOCTAVESPLIT_1: + g_midi_three_octave_split_1 = atol(line); + printf("Splitting THREE octaves top above %d%%\n", g_midi_three_octave_split_1); + if (g_midi_three_octave_split_1 < 0 || g_midi_three_octave_split_1 > 100) { + fprintf(stderr, "Invalid percentage in line: %s\n", _line); + exit(1); + } + g_midi_three_octave_split_1 = (256 * g_midi_three_octave_split_1) / 100; + split_done = 1; + break; + case KEYWORD_THREEOCTAVESPLIT_2: + g_midi_three_octave_split_2 = atol(line); + printf("Splitting THREE octaves bottom below %d%%\n", g_midi_three_octave_split_2); + if (g_midi_three_octave_split_2 < 0 || g_midi_three_octave_split_2 > 100) { + fprintf(stderr, "Invalid percentage in line: %s\n", _line); + return -1; + } + g_midi_three_octave_split_2 = (256 * g_midi_three_octave_split_2) / 100; + split_done = 1; + break; + case KEYWORD_MIDI_MAIN_CONTROL: + g_midi_main_control = atol(line); + printf("All Strings modify controller %d\n", g_midi_main_control); + if (g_midi_main_control > 127) { + fprintf(stderr, "Invalid controller number %d in line: %s\n", g_midi_main_control, _line); + return -1; + } + break; + case KEYWORD_MIDI_MAIN_CHANNEL: + g_midi_main_channel = atol(line); + printf("All Strings modify controller %d on channel %d\n", g_midi_main_control, g_midi_main_channel); + if (g_midi_main_channel < 1 || g_midi_main_channel > 16) { + fprintf(stderr, "Invalid channel number %d in line: %s\n", g_midi_main_channel, _line); + return -1; + } + break; + default: + fprintf(stderr, "Unhandled config line: %s\n", _line); + return -1; - // split also true for two octaves - if (g_midi_three_octave_split_2 < g_midi_three_octave_split_1) { - g_midi_three_octave_split_inverse = g_midi_three_octave_split_1; - g_midi_three_octave_split_1 = g_midi_three_octave_split_2; - g_midi_three_octave_split_2 = g_midi_three_octave_split_inverse; - g_midi_three_octave_split_inverse = 1; - } else - g_midi_three_octave_split_inverse = 0; } - fclose(fh); + if (!split_done) + return 0; + + /* split also true for two octaves */ + if (g_midi_three_octave_split_2 < g_midi_three_octave_split_1) { + g_midi_three_octave_split_inverse = g_midi_three_octave_split_1; + g_midi_three_octave_split_1 = g_midi_three_octave_split_2; + g_midi_three_octave_split_2 = g_midi_three_octave_split_inverse; + g_midi_three_octave_split_inverse = 1; + } else + g_midi_three_octave_split_inverse = 0; + + return 0; +} + +void +config_reset() +{ + //Reinitialise string config array + memset(g_string_conf, 0, sizeof(g_string_conf)); + g_current_string = 0; + g_max_y = 1024; } void -- cgit v1.2.3