/* * command.c * * Copyright © 2019 Thomas White * * This file is part of NanoLight. * * NanoLight is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include #include #include #include #define _(x) gettext(x) #include "nanolight.h" enum token_type { TK_FIXTURE, TK_AT, TK_DOT, TK_TO, TK_LEVEL, TK_ATTRIBUTE, }; struct token { enum token_type type; int fixture_index; int val; }; static int stop_char(char c) { if ( c == '@' ) return 1; if ( c == ' ' ) return 1; if ( c == '\0' ) return 1; if ( c == '.' ) return 1; if ( c == '-' ) return 1; return 0; } static int find_tokens(const char *cmd, struct token *tokens, struct nanolight *nl) { int i; int n = 0; int pos = 0; do { int start; char *word; unsigned long val; char *endptr; int done = 0; while ( isspace(cmd[pos]) ) pos++; start = pos; /* Is it an AT? */ if ( cmd[pos] == '@' ) { tokens[n++].type = TK_AT; pos++; continue; } /* Is it a dot? */ if ( cmd[pos] == '.' ) { tokens[n++].type = TK_DOT; pos++; continue; } /* Is it a dash? */ if ( cmd[pos] == '-' ) { tokens[n++].type = TK_TO; pos++; continue; } while ( !stop_char(cmd[pos]) ) pos++; word = strndup(cmd+start, pos-start); /* Is is a fixture name? */ for ( i=0; in_fixtures; i++ ) { if ( strcasecmp(nl->fixtures[i].label, word) == 0 ) { tokens[n].fixture_index = i; tokens[n++].type = TK_FIXTURE; done = 1; break; } } /* Is is an attribute name? */ for ( i=0; in_fixtures; i++ ) { if ( strcasecmp(nl->fixtures[i].label, word) == 0 ) { tokens[n].fixture_index = i; tokens[n++].type = TK_FIXTURE; done = 1; break; } } /* Is it a number? */ val = strtoul(word, &endptr, 10); if ( (word[0] != '\0') && (endptr[0] == '\0') ) { tokens[n].val = val; tokens[n++].type = TK_LEVEL; done = 1; } free(word); if ( !done ) return 0; } while ( cmd[pos] != '\0' ); return n; } static void show_tokens(struct token *tokens, int n, struct nanolight *nl) { int i; for ( i=0; ifixtures[tokens[i].fixture_index].label); break; case TK_AT: printf(" [@]"); break; case TK_DOT: printf(" [.]"); break; case TK_TO: printf(" [-]"); break; case TK_LEVEL: printf(" [value:%i]", tokens[i].val); break; } } printf("\n"); } int command_run(const char *cmd, struct nanolight *nl) { struct token tokens[1024]; int n; n = find_tokens(cmd, tokens, nl); if ( n == 0 ) return 1; show_tokens(tokens, n, nl); return 0; }