summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchatty1999-01-19 13:07:40 +0000
committerchatty1999-01-19 13:07:40 +0000
commita9a15b453b5dcca597fa4aeee5a2376ce1154b15 (patch)
tree827650e3958849146e821e7d56846e9f50a26f0b
parentd5c5e0bcd952c2b58fd02409d01b10da83872ef0 (diff)
downloadirbox-a9a15b453b5dcca597fa4aeee5a2376ce1154b15.zip
irbox-a9a15b453b5dcca597fa4aeee5a2376ce1154b15.tar.gz
irbox-a9a15b453b5dcca597fa4aeee5a2376ce1154b15.tar.bz2
irbox-a9a15b453b5dcca597fa4aeee5a2376ce1154b15.tar.xz
Added grammar and management of translation tables for events
irbox.c -> irman.c
-rw-r--r--gram.l113
-rw-r--r--gram.y190
-rw-r--r--irman.c (renamed from irbox.c)39
-rw-r--r--irtable.c111
-rw-r--r--irtable.h31
5 files changed, 469 insertions, 15 deletions
diff --git a/gram.l b/gram.l
new file mode 100644
index 0000000..95ddf1d
--- /dev/null
+++ b/gram.l
@@ -0,0 +1,113 @@
+%{
+/*
+ * This is a lexical analyzer
+ *
+ * It comes with an associated grammar.
+ *
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdio.h>
+
+/* header produced from the parser file with '-d' option of yacc */
+#include "y.tab.h"
+
+extern int tee (int);
+#define RETURN(x) return (tee(x))
+
+
+
+const char* ResWords [] = {
+ "type",
+ "name",
+ "brand",
+ 0
+};
+
+const int ResWordsTokens [] = {
+ Y_TYPE,
+ Y_NAME,
+ Y_BRAND
+};
+
+int LineNo = 1;
+
+void
+LexInit ()
+{
+
+#ifdef FLEX_SCANNER
+static void yyrestart (FILE*);
+// yyrestart (0);
+#endif
+ LineNo = 1;
+}
+
+
+int
+CheckResWord (const char* s)
+{
+ const char** pp = ResWords;
+ while (*pp) {
+ if (strcmp (*pp, s) == 0)
+ return pp - ResWords;
+ ++pp;
+ }
+ return -1;
+}
+
+
+%}
+
+
+
+Int [-]?[0-9]+
+Ident [a-zA-Z/\[\]][a-zA-Z.0-9/\[\]]*
+nl [\n]
+sp0 [ \t]*
+sp1 [ \t]+
+
+%%
+
+[:] RETURN (yytext[0]);
+
+\#.*\n { /* comments */
+ ++LineNo;
+ }
+
+\".*\" {
+ char* n = strdup (yytext+1);
+ n[strlen(yytext) - 1] = '\0';
+ yylval.name = n;
+ RETURN (Y_STRING);
+ }
+
+{sp1} {}
+
+{nl} {
+ ++LineNo;
+ RETURN (Y_EOL);
+ }
+
+{Int} {
+ yylval.integer = atoi (yytext);
+ RETURN (Y_INT);
+ }
+
+
+{Ident} {
+ int index = CheckResWord (yytext);
+ if (index >= 0) {
+ RETURN (ResWordsTokens[index]);
+ } else {
+ yylval.name = strdup (yytext);
+ RETURN (Y_ID);
+ }
+ }
+
+. {
+ RETURN (-1);
+ }
diff --git a/gram.y b/gram.y
new file mode 100644
index 0000000..2340390
--- /dev/null
+++ b/gram.y
@@ -0,0 +1,190 @@
+%{
+
+/*
+ *
+ * IRBOX, an Ivy driver for infra-red remote controls
+ *
+ * Copyright 1998-1999
+ * Centre d'Etudes de la Navigation Aerienne
+ *
+ * This is the grammar for reading tables
+ *
+ * $Id$
+ *
+ */
+
+extern const char* const ResWords;
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "irtable.h"
+
+extern int yyparse ();
+extern int yylex ();
+extern int LineNo;
+
+
+static char id_buf [1024]; /* Yeech */
+static char id_list_buf [4096]; /* Barf */
+
+static const char* filename = 0;
+static IrTable* cur_table;
+
+%}
+
+%union {
+ const char *name;
+ int integer;
+}
+
+%token Y_NAME Y_TYPE Y_BRAND Y_EOL
+%token <name> Y_ID Y_STRING
+%token <integer> Y_INT
+
+
+%type <name> id id_list
+
+%%
+
+instr_list:
+ /* empty */
+ | instr_list instr
+ ;
+
+id:
+ Y_ID
+ {
+ strcpy (id_buf, $1);
+ free ((char*) $1); /* was allocated by strdup in lex file */
+ $$ = id_buf;
+ }
+ | Y_INT
+ {
+ sprintf (id_buf, "%d", $1);
+ $$ = id_buf;
+ }
+ ;
+
+id_list:
+ id
+ {
+ strcpy (id_list_buf, $1);
+ $$ = $1;
+ }
+ | id_list id
+ {
+ strcat (id_list_buf, " ");
+ strcat (id_list_buf, $2);
+ $$ = id_list_buf;
+ }
+ ;
+
+instr:
+ Y_EOL
+
+ | Y_NAME Y_ID Y_EOL
+ {
+ IrTableName (cur_table, $2);
+ }
+
+ | Y_TYPE ':' Y_ID Y_EOL
+ {
+ IrTableType (cur_table, $3);
+ }
+
+ | Y_BRAND ':' id_list Y_EOL
+ {
+ IrTableAddBrand (cur_table, $3);
+ }
+
+ | id_list ':' Y_INT Y_INT Y_INT Y_INT Y_INT Y_INT Y_EOL
+ {
+ IrTableAddKey (cur_table, $1, $3, $4, $5, $6, $7, $8);
+ }
+ ;
+
+
+%%
+#include <stdio.h>
+
+int _DoTee = 0;
+
+int
+tee (int x)
+{
+ if (_DoTee) {
+ char *s;
+ switch (x) {
+ case ':':
+ s = ":";
+ break;
+ case Y_EOL:
+ s = "Y_EOL\n";
+ break;
+ case Y_STRING:
+ s = "STRING";
+ break;
+ case Y_INT:
+ s = "INT";
+ break;
+ case Y_ID:
+ s = "ID";
+ break;
+ case Y_TYPE:
+ s = "TYPE";
+ break;
+ case Y_BRAND:
+ s = "BRAND";
+ break;
+/* case Y_:
+ s = "";
+ break;
+*/
+ default :
+ s = "???";
+ break;
+ }
+ printf ("%s ", s);
+ }
+ return x;
+}
+
+
+int
+yyerror (const char *s)
+{
+ fprintf (stderr, "%s in %s, line %d\n", s, filename, LineNo);
+ return (0);
+}
+
+int
+yywrap ()
+{
+ return 1;
+}
+
+
+IrTable*
+IrTableReadFile (const char* file)
+{
+ extern void LexInit ();
+ extern FILE *yyin;
+ int result;
+
+ LexInit ();
+ filename = file;
+ if (!(yyin = fopen (file,"r"))) {
+ char err [1024];
+ fprintf (stderr, "Cannot open %s\n", file);
+ return 0;
+ }
+ cur_table = IrCreateTable ();
+ if (yyparse ()) {
+ result = 0;
+ }
+ fclose (yyin);
+ return cur_table;
+}
+
diff --git a/irbox.c b/irman.c
index 07f35b7..9f70163 100644
--- a/irbox.c
+++ b/irman.c
@@ -25,6 +25,7 @@
#include "ivychannel.h"
#include "irdev.h"
+#include "irtable.h"
#define DEFAULT_DEVICE "/dev/ttyS1"
@@ -59,24 +60,25 @@ IrUntimeout (void *id)
}
static void
-IrEventCb (IrState *ir, IrEvent event, const char* value)
+IrEventCb (IrState *ir, const unsigned char* code)
{
- switch (event) {
- case EVENT_BTN_RELEASE:
- IvySendMsg ("%s BUTTON %s UP", app_name, value);
- break;
-
- case EVENT_BTN_PRESS_TV_VOL_UP:
- IvySendMsg ("%s BUTTON %s DOWN", app_name, "TV:VOL_UP");
- break;
-
-
- default:
- IvySendMsg ("%s BUTTON %s DOWN", app_name, value);
- break;
+ IrTable* t;
+ const char* key;
+ if (IrTableTranslateCode (code, &t, &key)) {
+ IvySendMsg ("%s Down control=%s button=%s", app_name, t->name, key);
+ } else {
+ IvySendMsg ("%s unknown code %.3d %.3d %.3d %.3d %.3d %.3d", app_name, code[0], code[1],code[2],code[3],code[4],code[5]);
+ fprintf (stderr, "unknown code %.3d %.3d %.3d %.3d %.3d %.3d\n", code[0], code[1],code[2],code[3],code[4],code[5]);
}
}
+static void
+IrFailCb (IrState* ir)
+{
+ fprintf(stderr,"IR box not responding.\n");
+ IvySendMsg ("%s Failed", app_name);
+ IvyStop ();
+}
int
main (int argc, char *argv[])
@@ -115,9 +117,16 @@ main (int argc, char *argv[])
return -1;
}
- if (!IrInit (ir, IrEventCb, IrTimeout, IrUntimeout))
+ if (!IrInit (ir, IrEventCb, IrFailCb, IrTimeout, IrUntimeout))
return -1;
+ IrTableReadFile ("tables/akaiVCR1.ir");
+ IrTableReadFile ("tables/akaiVCR2.ir");
+ IrTableReadFile ("tables/rcaTV1.ir");
+ IrTableReadFile ("tables/rcaVCR1.ir");
+ IrTableReadFile ("tables/sonyTV.ir");
+ IrTableReadFile ("tables/sonyVCR1.ir");
+
IvyInit (app_name, bport, 0, 0, 0, 0, 0);
IvyChannelSetUp (IrGetFd (ir), ir, 0, Handle);
diff --git a/irtable.c b/irtable.c
new file mode 100644
index 0000000..9be02fa
--- /dev/null
+++ b/irtable.c
@@ -0,0 +1,111 @@
+#include "irtable.h"
+#include "irdev.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+typedef struct _irtablecell IrTableCell;
+
+struct _irtablecell {
+ IrTable* table;
+ unsigned char code[6];
+ const char* key;
+ IrTableCell* next;
+};
+
+
+
+
+IrTable*
+IrCreateTable ()
+{
+ return (IrTable*) malloc (sizeof (IrTable));
+}
+
+void
+IrTableName (IrTable* t, const char* n)
+{
+ t->name = strdup (n);
+}
+
+void
+IrTableType (IrTable* t, const char* type)
+{
+ t->type = strdup (type);
+}
+
+void
+IrTableAddBrand (IrTable* t, const char* b)
+{
+}
+
+
+
+#define KEYCELLS 127
+#define CODECELLS 1023
+
+static IrTableCell* KeyToCell [KEYCELLS];
+static IrTableCell* CodeToCell [CODECELLS];
+
+static unsigned int
+IrHashKey (const char* key)
+{
+ register unsigned int h = 0;
+ register const char* p = key;
+ while (*p)
+ h += (h << 3) + *p++; /* this hash function was stolen from Tcl */
+ return h % KEYCELLS;
+}
+
+static unsigned int
+IrHashCode (const unsigned char* code)
+{
+ register unsigned int h = 0;
+ register const unsigned char* p = code;
+ register const unsigned char* q = p+6;
+ while (p < q)
+ h += (h << 3) + *p++; /* A ADAPTER */
+ return h % CODECELLS;
+}
+
+void
+IrTableAddKey (IrTable* t, const char* k, int c0, int c1, int c2, int c3 , int c4, int c5)
+{
+ IrTableCell* c = (IrTableCell*) malloc (sizeof (IrTableCell));
+ IrTableCell** cc;
+
+ c->table = t;
+ c->key = strdup (k);
+ c->code[0] = c0;
+ c->code[1] = c1;
+ c->code[2] = c2;
+ c->code[3] = c3;
+ c->code[4] = c4;
+ c->code[5] = c5;
+ cc = CodeToCell + IrHashCode (c->code);
+ /* GERER LES COLLISIONS */
+ c->next = *cc;
+ *cc = c;
+}
+
+int
+IrTableTranslateCode (const unsigned char* code, IrTable** table, const char** key)
+{
+ IrTableCell* c;
+
+ c = CodeToCell [IrHashCode (code)];
+ while (c) {
+ if (strncmp (code, c->code, 6) == 0)
+ break;
+ c = c->next;
+ }
+ if (c) {
+ if (table) *table = c->table;
+ if (key) *key = c->key;
+ } else {
+ if (table) *table = 0;
+ if (key) *key = 0;
+ }
+ return (int) (c);
+}
+
diff --git a/irtable.h b/irtable.h
new file mode 100644
index 0000000..ed751fd
--- /dev/null
+++ b/irtable.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * IRBOX, an Ivy driver for infra-red remote controls
+ *
+ * Copyright 1998-1999
+ * Centre d'Etudes de la Navigation Aerienne
+ *
+ * Tables for decoding events
+ *
+ * $Id$
+ *
+ */
+
+#ifndef irtable_h_
+#define irtable_h_
+
+typedef struct {
+ const char* name;
+ const char* type;
+} IrTable;
+
+extern IrTable* IrTableReadFile (const char*);
+extern IrTable* IrCreateTable ();
+extern void IrTableName (IrTable*, const char*);
+extern void IrTableType (IrTable*, const char*);
+extern void IrTableAddBrand (IrTable*, const char*);
+extern void IrTableAddKey (IrTable*, const char*, int, int, int, int, int, int);
+
+extern int IrTableTranslateCode (const unsigned char*, IrTable**, const char**);
+
+#endif /* irtable_h_ */