/* * 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 "lightctx.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 attribute; int val; }; /* Tables for converting between attribute class numbers and names */ const char *attr_class_names[] = { "int", }; int attr_classes[] = { INTENSITY, }; int n_attr_classes = 1; /* (end of attribute tables) */ 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 lightctx *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; 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; case TK_ATTRIBUTE: printf(" [attr:%s]", str_attr(tokens[i].attribute)); break; } } printf("\n"); } static void set_level(struct lightctx *nl, int val) { int i; for ( i=0; in_sel; i++ ) { struct fixture *fix = &nl->fixtures[nl->selection[i]]; fix->intensity = (float)val/100.0; } } int command_run(const char *cmd, struct lightctx *nl) { struct token tokens[1024]; int i, n; n = find_tokens(cmd, tokens, nl); if ( n == 0 ) return 1; show_tokens(tokens, n, nl); i = 0; if ( tokens[i].type == TK_FIXTURE ) { nl->n_sel = 0; for ( i=0; iselection[nl->n_sel++] = tokens[i].fixture_index; } else { break; } } } if ( tokens[i].type == TK_AT ) { if ( tokens[i+1].type == TK_LEVEL ) { set_level(nl, tokens[i+1].val); } } return 0; }