From 83cf5fbbdcc74e8d65627ed84f8906988aecfc4e Mon Sep 17 00:00:00 2001
From: Anders Blomdell <anders.blomdell@control.lth.se>
Date: Tue, 19 Feb 2019 11:57:44 +0100
Subject: [PATCH] Parsing working for first example

---
 moberg_config_parser.h          |  20 +++--
 moberg_driver.c                 |  20 +++--
 moberg_driver.h                 |  11 +--
 modules/comedi/comedi.c         |  79 ++++++++++++--------
 modules/serial2002/serial2002.c |  88 +++++++++++++++++-----
 parse_config.c                  | 128 ++++++++++++++++++--------------
 test/a/moberg.conf              |  14 ++--
 7 files changed, 226 insertions(+), 134 deletions(-)

diff --git a/moberg_config_parser.h b/moberg_config_parser.h
index faf48f1..d968b50 100644
--- a/moberg_config_parser.h
+++ b/moberg_config_parser.h
@@ -8,14 +8,18 @@ struct moberg_config_parser_token;
 
 enum moberg_config_parser_token_kind {
   tok_none,
-  tok_LBRACE = '{',
-  tok_RBRACE = '}',
-  tok_LBRACKET = '[',
-  tok_RBRACKET = ']',
-  tok_EQUAL = '=',
-  tok_COLON = ':',
-  tok_SEMICOLON = ';',
-  tok_INTEGER = 256,
+  tok_EOF,
+  tok_LPAREN,
+  tok_RPAREN,
+  tok_LBRACE,
+  tok_RBRACE,
+  tok_LBRACKET,
+  tok_RBRACKET,
+  tok_EQUAL,
+  tok_COMMA,
+  tok_COLON,
+  tok_SEMICOLON,
+  tok_INTEGER,
   tok_IDENT,
   tok_STRING,
 };
diff --git a/moberg_driver.c b/moberg_driver.c
index a732345..1780950 100644
--- a/moberg_driver.c
+++ b/moberg_driver.c
@@ -4,21 +4,29 @@
 #include <moberg_driver.h>
 #include <dlfcn.h>
 
-struct moberg_driver *moberg_open_driver(struct moberg_config_parser_ident id)
+struct moberg_driver *moberg_driver_open(struct moberg_config_parser_ident id)
 {
   struct moberg_driver *result = NULL;
 
   char *driver_name = malloc(sizeof("libmoberg_.so") + id.length + 1);
   if (!driver_name) { goto out; }
   sprintf(driver_name, "libmoberg_%.*s.so", id.length, id.value);
-  printf("%s", driver_name);
   void *handle = dlopen(driver_name, RTLD_LAZY || RTLD_DEEPBIND);
-  if (! handle) { goto free_driver_name; }
+  if (! handle) {
+    fprintf(stderr, "Could not find driver %s\n", driver_name);
+    goto free_driver_name;
+  }
   struct moberg_driver_module *module =
     (struct moberg_driver_module *) dlsym(handle, "moberg_module");
-  if (! module) { goto dlclose_driver; }
+  if (! module) {
+    fprintf(stderr, "No moberg_module in driver %s\n", driver_name);
+    goto dlclose_driver;
+  }
   result = malloc(sizeof(*result));
-  if (! result) { goto dlclose_driver; }
+  if (! result) {
+    fprintf(stderr, "Could not allocate result for %s\n", driver_name);
+    goto dlclose_driver;
+  }
   result->handle = handle;
   result->module = *module;
   goto free_driver_name;
@@ -31,7 +39,7 @@ out:
     return result;
 }
 
-void moberg_close_driver(struct moberg_driver *driver)
+void moberg_driver_close(struct moberg_driver *driver)
 {
   dlclose(driver->handle);
   free(driver);
diff --git a/moberg_driver.h b/moberg_driver.h
index e7986f8..a774da5 100644
--- a/moberg_driver.h
+++ b/moberg_driver.h
@@ -3,13 +3,12 @@
 
 #include <moberg_config_parser.h>
 
-struct moberg_driver_config {
-};
+struct moberg_driver_device;
 
 struct moberg_driver_map {
 };
 
-typedef struct moberg_driver_config (*moberg_driver_parse_config_t)(
+typedef struct moberg_driver_device *(*moberg_driver_parse_config_t)(
   struct moberg_config_parser_context *context);
 
 typedef struct moberg_driver_map (*moberg_driver_parse_map_t)(
@@ -24,9 +23,11 @@ struct moberg_driver {
   } module;
 };
 
-struct moberg_driver *moberg_open_driver(struct moberg_config_parser_ident id);
+struct moberg_driver *moberg_driver_open(struct moberg_config_parser_ident id);
+
+void moberg_driver_close(struct moberg_driver *driver);
 
-void moberg_close_driver(struct moberg_driver *driver);
+void moberg_driver_device_free(struct moberg_driver_device *device);
 
 
 #endif
diff --git a/modules/comedi/comedi.c b/modules/comedi/comedi.c
index b91b055..f5ae143 100644
--- a/modules/comedi/comedi.c
+++ b/modules/comedi/comedi.c
@@ -22,57 +22,64 @@ static inline int acceptkeyword(context_t *c,
   return moberg_config_parser_acceptkeyword(c, keyword);
 }
   
+struct moberg_driver_device {
+  const char *device;
+};
+
 
-static struct moberg_driver_config parse_config(
+static struct moberg_driver_device *parse_config(
   struct moberg_config_parser_context *c)
 {
-  struct moberg_driver_config result;
-  token_t t;
-  printf("PARSE_CONFIG %s\n", __FILE__);
-  printf("LBRACE %d", acceptsym(c, tok_LBRACE, &t));
+  struct moberg_driver_device *result = malloc(sizeof *result);
+  if (! result) {
+    fprintf(stderr, "Failed to allocate moberg device\n");
+    goto err;
+  }
+  if (! acceptsym(c, tok_LBRACE, NULL)) { goto syntax_err; }
   for (;;) {
     if (acceptsym(c, tok_RBRACE, NULL)) {
 	break;
     } else if (acceptkeyword(c, "device")) {
       token_t device;
-      if (! acceptsym(c, tok_EQUAL, NULL)) { goto err; }
-      if (! acceptsym(c, tok_STRING, &device)) { goto err; }
-      if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto err; }
+      if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
+      if (! acceptsym(c, tok_STRING, &device)) { goto syntax_err; }
+      if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
+      result->device = strndup(device.u.string.value, device.u.string.length);
     } else if (acceptkeyword(c, "config")) {
-      if (! acceptsym(c, tok_EQUAL, NULL)) { goto err; }
-      if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
+      if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
+      if (! acceptsym(c, tok_LBRACKET, NULL)) { goto syntax_err; }
       for (;;) {
 	if (acceptsym(c, tok_RBRACKET, NULL)) {
 	  break;
 	} else if (acceptsym(c, tok_IDENT, NULL) ||
 		   acceptsym(c, tok_STRING, NULL)) {
 	} else {
-	  goto err;
+	  goto syntax_err;
 	}
       }
-      if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto err; }
+      if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
     } else if (acceptkeyword(c, "modprobe")) {
-      if (! acceptsym(c, tok_EQUAL, NULL)) { goto err; }
-      if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
+      if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
+      if (! acceptsym(c, tok_LBRACKET, NULL)) { goto syntax_err; }
       for (;;) {
 	if (acceptsym(c, tok_RBRACKET, NULL)) {
 	  break;
 	} else if (acceptsym(c, tok_IDENT, NULL) ||
 		   acceptsym(c, tok_STRING, NULL)) {
 	} else {
-	  goto err;
+	  goto syntax_err;
 	}
       }
-      if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto err; }
+      if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
     } else {
-      goto err;
+      goto syntax_err;
     }
   }
-  printf("PARSE_CONFIG DONE%s\n", __FILE__);
   return result;
- err:
+syntax_err:
   moberg_config_parser_failed(c, stderr);
-  exit(1);
+err:
+  return NULL;
 }
 
 static struct moberg_driver_map parse_map(
@@ -81,20 +88,26 @@ static struct moberg_driver_map parse_map(
 {
   struct moberg_driver_map result;
 
-  token_t t;
-  printf("PARSE_MAP %s\n", __FILE__);
-  if (! acceptkeyword(c, "subdevice") != 0) {  goto err; }
-  if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
-  if (! acceptsym(c, tok_INTEGER, &t)) { goto err; }
-  if (! acceptsym(c, tok_RBRACKET, NULL)) { goto err; }
-    
-/*
-  const char *buf = context->buf;
-  while (*buf && *buf != '}') {
-    buf++;
+  if (! acceptsym(c, tok_LBRACE, NULL)) { goto err; }
+  for (;;) {
+    token_t subdevice;
+    if (! acceptkeyword(c, "subdevice") != 0) {  goto err; }
+    if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
+    if (! acceptsym(c, tok_INTEGER, &subdevice)) { goto err; }
+    if (! acceptsym(c, tok_RBRACKET, NULL)) { goto err; }
+    if (acceptkeyword(c, "route")) {
+      token_t route;
+      if (! acceptsym(c, tok_INTEGER, &route)) { goto err; }
+    }
+    if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
+    if (! acceptsym(c, tok_INTEGER, NULL)) { goto err; }
+    if (acceptsym(c, tok_COLON, NULL)) { 
+      if (! acceptsym(c, tok_INTEGER, NULL)) { goto err; }
+    }
+    if (! acceptsym(c, tok_RBRACKET, NULL)) { goto err; }
+    if (! acceptsym(c, tok_COMMA, NULL)) { break; }
   }
-  context->buf = buf + 1;
-*/
+  if (! acceptsym(c, tok_RBRACE, NULL)) { goto err; }
   return result;
 err:
   moberg_config_parser_failed(c, stderr);
diff --git a/modules/serial2002/serial2002.c b/modules/serial2002/serial2002.c
index a34e526..af26b0c 100644
--- a/modules/serial2002/serial2002.c
+++ b/modules/serial2002/serial2002.c
@@ -1,38 +1,90 @@
 #include <moberg_config_parser.h>
 #include <moberg_driver.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
-static struct moberg_driver_config parse_config(
-  struct moberg_config_parser_context *context)
+typedef enum moberg_config_parser_token_kind kind_t;
+typedef struct moberg_config_parser_token token_t;
+typedef struct moberg_config_parser_ident ident_t;
+typedef struct moberg_config_parser_context context_t;
+
+static inline int acceptsym(context_t *c,
+			   kind_t kind,
+			   token_t *token)
+{
+  return moberg_config_parser_acceptsym(c, kind, token);
+}
+  
+static inline int acceptkeyword(context_t *c,
+				const char *keyword)
 {
-  struct moberg_driver_config result;
+  return moberg_config_parser_acceptkeyword(c, keyword);
+}
+  
+struct moberg_driver_device {
+  const char *device;
+  int baud;
+};
+
 
-  printf("PARSE_CONFIG %s\n", __FILE__);
-/*
-  const char *buf = context->buf;
-  while (*buf && *buf != '}') {
-    buf++;
+static struct moberg_driver_device *parse_config(
+  struct moberg_config_parser_context *c)
+{
+  struct moberg_driver_device *result = malloc(sizeof *result);
+  if (! result) {
+    fprintf(stderr, "Failed to allocate moberg device\n");
+    goto err;
+  }
+  if (! acceptsym(c, tok_LBRACE, NULL)) { goto syntax_err; }
+  for (;;) {
+    if (acceptsym(c, tok_RBRACE, NULL)) {
+	break;
+    } else if (acceptkeyword(c, "device")) {
+      token_t device;
+      if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
+      if (! acceptsym(c, tok_STRING, &device)) { goto syntax_err; }
+      if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
+      result->device = strndup(device.u.string.value, device.u.string.length);
+    } else if (acceptkeyword(c, "baud")) {
+      token_t baud;
+      if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
+      if (! acceptsym(c, tok_INTEGER, &baud)) { goto syntax_err; }
+      if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
+      result->baud = baud.u.integer.value;
+    } else {
+      goto syntax_err;
+    }
   }
-  context->buf = buf + 1;
-*/
   return result;
+syntax_err:
+  moberg_config_parser_failed(c, stderr);
+err:
+  return NULL;
 }
 
 static struct moberg_driver_map parse_map(
-  struct moberg_config_parser_context *context,
+  struct moberg_config_parser_context *c,
   enum moberg_config_parser_token_kind kind)
 {
   struct moberg_driver_map result;
 
-  printf("PARSE_MAP %s\n", __FILE__);
-/*
-  const char *buf = context->buf;
-  while (*buf && *buf != '}') {
-    buf++;
+  if (acceptkeyword(c, "analog_in") ||
+      acceptkeyword(c, "analog_out") ||
+      acceptkeyword(c, "digital_in") ||
+      acceptkeyword(c, "digital_out") ||
+      acceptkeyword(c, "encoder_in")) {
+    if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
+    if (! acceptsym(c, tok_INTEGER, NULL)) { goto err; }
+    if (acceptsym(c, tok_COLON, NULL)) { 
+      if (! acceptsym(c, tok_INTEGER, NULL)) { goto err; }
+    }
+    if (! acceptsym(c, tok_RBRACKET, NULL)) { goto err; }
   }
-  context->buf = buf + 1;
-*/
   return result;
+err:
+  moberg_config_parser_failed(c, stderr);
+  exit(1);
 }
 
 struct moberg_driver_module moberg_module = {
diff --git a/parse_config.c b/parse_config.c
index f6f4659..53bde81 100644
--- a/parse_config.c
+++ b/parse_config.c
@@ -27,7 +27,6 @@ static inline int acceptkeyword(context_t *c,
 }
  
 #define MAX_EXPECTED 10
-static char expected_char[256][2];
 
 typedef struct moberg_config_parser_context {
   char *buf;      /* Pointer to data to be parsed */
@@ -41,6 +40,7 @@ typedef struct moberg_config_parser_context {
 
 static const void nextsym_ident(context_t *c)
 {
+  c->token.kind = tok_IDENT;
   c->token.u.ident.length = 1;
   c->token.u.ident.value = c->p;
   c->p++;
@@ -54,15 +54,9 @@ static const void nextsym_ident(context_t *c)
         c->token.u.ident.length++;
         break;
       default:
-        goto out;
-        break;
+        return;
     }
   }
-out: ;
-  const char *v = c->token.u.ident.value;
-  int l = c->token.u.ident.length;
-  c->token.kind = tok_IDENT;
-  printf("IDENT: %.*s %d\n", l, v, c->token.kind);
 }
 
 static const void nextsym_integer(context_t *c)
@@ -74,12 +68,10 @@ static const void nextsym_integer(context_t *c)
     c->token.u.integer.value += *c->p - '0';
     c->p++;
   }
-  printf("INTEGER: %d\n", c->token.u.integer.value);
 }
 
 static const void nextsym_string(context_t *c)
 {
-  printf("STTRING");
   c->token.kind = tok_STRING;
   c->p++;
   c->token.u.string.value = c->p;
@@ -95,7 +87,6 @@ static const void nextsym_string(context_t *c)
     }
   }
   c->p++;
-  printf("STRING: %.*s\n", c->token.u.string.length, c->token.u.string.value);
 }
 
 static int nextsym(context_t *c)
@@ -103,7 +94,6 @@ static int nextsym(context_t *c)
   c->token.kind = tok_none;
   while (c->p && *c->p && c->token.kind == tok_none) {
     if (c->p[0] == '/' && c->p[1] == '*') {
-      printf("Skipping COMMENT\n");
       /* Skip comment */
       c->p += 2;
       while (*c->p && (c->p[0] != '*' || c->p[1] != '/')) {
@@ -120,6 +110,14 @@ static int nextsym(context_t *c)
         /* Skip whitespace */
         c->p++;
         break;
+      case '(':
+        c->token.kind = tok_LPAREN;
+        c->p++;
+        break;
+      case ')':
+        c->token.kind = tok_RPAREN;
+        c->p++;
+        break;
       case '{':
         c->token.kind = tok_LBRACE;
         c->p++;
@@ -140,6 +138,10 @@ static int nextsym(context_t *c)
         c->token.kind = tok_EQUAL;
         c->p++;
         break;
+      case ',':
+        c->token.kind = tok_COMMA;
+        c->p++;
+        break;
       case ':':
         c->token.kind = tok_COLON;
         c->p++;
@@ -165,10 +167,10 @@ static int nextsym(context_t *c)
         break;
     }
   }
-  printf("TOKEN %d %c\n\n", c->token.kind, c->token.kind<255?c->token.kind:' ');
   if (c->token.kind != tok_none) {
     return 1;
   } else {
+    c->token.kind = tok_EOF;
     return 0;
   }
 }
@@ -191,7 +193,6 @@ int moberg_config_parser_acceptsym(context_t *c,
                                    token_t *token)
 {
   if (c->token.kind == kind) {
-    printf("ACCEPT %d %s", c->token.kind, expected_char[kind]);
     if (token) {
       *token = c->token;
     }
@@ -203,13 +204,17 @@ int moberg_config_parser_acceptsym(context_t *c,
     const char *what = NULL;
     switch (kind) {
     case tok_none: break;
+      case tok_EOF: what = "<EOF>"; break;
+    case tok_LPAREN: what = "("; break;
+    case tok_RPAREN: what = ")"; break;
     case tok_LBRACE: what = "{"; break;
     case tok_RBRACE: what = "}"; break;
     case tok_LBRACKET: what = "["; break;
     case tok_RBRACKET: what = "]"; break;
     case tok_EQUAL: what = "="; break;
+    case tok_COMMA: what = ","; break;
     case tok_COLON: what = ":"; break;
-    case tok_SEMICOLON: what = "y;"; break;
+    case tok_SEMICOLON: what = ";"; break;
     case tok_INTEGER: what = "<INTEGER>"; break;
     case tok_IDENT: what = "<IDENT>"; break;
     case tok_STRING: what = "<STRING>"; break;
@@ -219,7 +224,6 @@ int moberg_config_parser_acceptsym(context_t *c,
       c->expected.n++;
     }
   }
-  printf("REJECT %d (%d)", kind, c->token.kind);
   return 0;
 }
 
@@ -245,25 +249,39 @@ void moberg_config_parser_failed(
   FILE *f)
 {
   fprintf(f, "EXPECTED ");
-  for (int i = 0 ; i < c->expected.n ; i++) {
-    fprintf(f, "%s ", c->expected.what[i]);
+  for (int i = 0 ; i < c->expected.n; i++) {
+    if (i > 0) {
+      fprintf(f, " | ");
+    }
+    fprintf(f, "'%s'", c->expected.what[i]);
   }
-  const char *what = "";
+  fprintf(f, "\nGOT: ");
   switch (c->token.kind) {
-  case tok_none: break;
-  case tok_LBRACE: what = "{"; break;
-  case tok_RBRACE: what = "}"; break;
-  case tok_LBRACKET: what = "["; break;
-  case tok_RBRACKET: what = "]"; break;
-  case tok_EQUAL: what = "="; break;
-  case tok_COLON: what = ":"; break;
-  case tok_SEMICOLON: what = ";"; break;
-  case tok_INTEGER: what = "<INTEGER>"; break;
-  case tok_IDENT: what = "<IDENT>"; break;
-  case tok_STRING: what = "<STRING>"; break;
+    case tok_none: break;
+    case tok_EOF: fprintf(f, "<EOF>"); break;
+    case tok_LPAREN: fprintf(f, "("); break;
+    case tok_RPAREN: fprintf(f, ")"); break;
+    case tok_LBRACE: fprintf(f, "{"); break;
+    case tok_RBRACE: fprintf(f, "}"); break;
+    case tok_LBRACKET: fprintf(f, "["); break;
+    case tok_RBRACKET: fprintf(f, "]"); break;
+    case tok_EQUAL: fprintf(f, "="); break;
+    case tok_COMMA: fprintf(f, ","); break;
+    case tok_COLON: fprintf(f, ":"); break;
+    case tok_SEMICOLON: fprintf(f, ";"); break;
+    case tok_INTEGER:
+      fprintf(f, "%d (<INTEGER>)", c->token.u.integer.value);
+      break;
+    case tok_IDENT:
+      fprintf(f, "%.*s (<IDENT>)",
+              c->token.u.ident.length, c->token.u.ident.value);
+      break;
+    case tok_STRING:
+      fprintf(f, "\"%.*s'\" (<STRING>)",
+              c->token.u.string.length, c->token.u.string.value);
+      break;
   }
-  
-  fprintf(f, "\nGOT %s %s\n", what, c->p);
+  fprintf(f, "\n%s\n", c->p);
 }
 
 
@@ -288,7 +306,6 @@ err:
 static int parse_map(context_t *c,
                      struct moberg_driver *driver)
 {
-  printf("parsemap");
   if (acceptkeyword(c, "analog_in") ||
       acceptkeyword(c, "analog_out") ||
       acceptkeyword(c, "digital_in") ||
@@ -297,7 +314,6 @@ static int parse_map(context_t *c,
     if (! parse_map_range(c)) { goto err; }
     if (! acceptsym(c, tok_EQUAL, NULL)) { goto err; }
     driver->module.parse_map(c, 0);
-    if (! parse_map_range(c)) { goto err; }
     if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto err; }
   } else {
     goto err;
@@ -329,36 +345,34 @@ err:
   return 0;
 }
 
-static int parse_driver(context_t *c,
-                        ident_t name)
-{
-  struct moberg_driver *driver = moberg_open_driver(name);
-  if (! driver) {
-    printf("Driver not found\n");
-    goto err;
-  } else {
-    int OK = parse_device(c, driver);
-    moberg_close_driver(driver);
-    if (! OK) { goto err; } 
-  }
-  return 1;
-err:
-  return 0;
-}
-
 static int parse_config(context_t *c)
 {
   for (;;) {
-    token_t t;
-    if (acceptsym(c, tok_IDENT, &t)) {
-      printf("DRIVER=%.*s\n", t.u.ident.length, t.u.ident.value);
-      if (! parse_driver(c, t.u.ident)) { goto err; }
+    if (acceptsym(c, tok_EOF, NULL)) {
+      break;
+    } else {
+      token_t t;
+      struct moberg_driver *driver;
+      
+      if (! acceptkeyword(c, "driver")) { goto syntax_err; }
+      if (! acceptsym(c, tok_LPAREN, NULL)) { goto syntax_err; }
+      if (! acceptsym(c, tok_IDENT, &t)) { goto syntax_err; }
+      if (! acceptsym(c, tok_RPAREN, NULL)) { goto syntax_err; }
+      
+      if (! (driver = moberg_driver_open(t.u.ident))) { goto driver_not_found; }
+      int OK = parse_device(c, driver);
+      moberg_driver_close(driver);
+      if (! OK) { goto err; }
     }
   }
   return 1;
+syntax_err:  
+  moberg_config_parser_failed(c, stderr);
+  goto err;
+driver_not_found:
+  fprintf(stderr, "Could not open\n");
+  goto err;
 err:
-  printf("Failed!!");
-  exit (1);
   return 0;
 }
 
diff --git a/test/a/moberg.conf b/test/a/moberg.conf
index 81092d1..9523ce1 100644
--- a/test/a/moberg.conf
+++ b/test/a/moberg.conf
@@ -1,4 +1,4 @@
-comedi {
+driver(comedi) {
     config {
         /* Parsed by parse_config in libmoberg_comedi.so */
         device = "/dev/comedi0" ;
@@ -7,13 +7,13 @@ comedi {
     }
     /* Moberg mapping[indices] = {driver specific}[indices]
       {driver specific} is parsed by parse_map in libmoberg_comedi.so */
-    map analog_in[0:7] = subdevice[0][0:7] ;
-    map analog_out[0:1] = subdevice[1][0:1] ;
-    map digital_in[0] = subdevice[7][15] ;
-    map digital_in[1] = subdevice[7][2] ;
-    map digital_out[0:1] = subdevice[7] route 16 [0:1];
+    map analog_in[0:7] = { subdevice[0][0:7] };
+    map analog_out[0:1] = { subdevice[1][0:1] };
+    map digital_in[0:1] = { subdevice[7][15] ,
+                            subdevice[7][2] };
+    map digital_out[0:1] = { subdevice[7] route 16 [0:1] };
 }
-serial2002 {
+driver(serial2002) {
     config {
         /* Parsed by parse_config in libmoberg_serial2002.so */
         device = "/dev/ttyS0" ;
-- 
GitLab