From 665fffdeebe594161287b14dd1191402fd18166d Mon Sep 17 00:00:00 2001 From: mdw Date: Wed, 30 Jan 2002 09:23:58 +0000 Subject: [PATCH] Follow new transport configuration interface. Add parameters for flow control. Break the format into separate parameters for independent configuration. --- serial.c | 210 +++++++++++++++++++++++++++++++++++++++++---------------------- serial.h | 24 +++++--- 2 files changed, 153 insertions(+), 81 deletions(-) diff --git a/serial.c b/serial.c index 65f0417..b7294b0 100644 --- a/serial.c +++ b/serial.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: serial.c,v 1.1 2002/01/25 19:34:45 mdw Exp $ + * $Id: serial.c,v 1.2 2002/01/30 09:23:58 mdw Exp $ * * Common serial functionality * @@ -29,6 +29,11 @@ /*----- Revision history --------------------------------------------------* * * $Log: serial.c,v $ + * Revision 1.2 2002/01/30 09:23:58 mdw + * Follow new transport configuration interface. Add parameters for flow + * control. Break the format into separate parameters for independent + * configuration. + * * Revision 1.1 2002/01/25 19:34:45 mdw * Initial revision * @@ -105,93 +110,144 @@ done: return (x); } -/* --- @serial_parse@ --- * +/* --- @getparity@ --- * * - * Arguments: @const char *p@ = configuration string to parse - * @serial_config *sc@ = pointer to serial config structure + * Arguments: @const char *p@ = pointer to string + * @const char **pp@ = where to store final pointer * - * Returns: Zero if OK, or @-1@ on error. + * Returns: Parity constant or @-1@ on error. * - * Use: Parses a serial config string into something more - * reasonable. The config structure should have been - * initialized to something sensible (e.g., @SERIAL_INIT@) - * already. + * Use: Parses a parity setting. */ -int serial_parse(const char *p, serial_config *sc) +static int getparity(const char *p, const char **pp) { - long x; const char *q; - char *qq; - - /* --- Pick out an initial baud rate --- */ - - while (isspace((unsigned char)*p)) - p++; - if (*p != 0 && *p != ':') { - if ((x = getbaud(p, &p)) < 0) - goto fail; - sc->baud = x; - } - while (isspace((unsigned char)*p)) - p++; - if (*p == ':') - p++; - /* --- Pick out a word length --- */ + for (q = p; isalpha((unsigned char)*q); q++) + ; + if (q == p) + return (-1); + if (pp) + *pp = q; + if (strncmp(p, "none", q - p) == 0) + return (PARITY_NONE); + else if (strncmp(p, "odd", q - p) == 0) + return (PARITY_ODD); + else if (strncmp(p, "even", q - p) == 0) + return (PARITY_EVEN); + else + return (-1); +} - while (isspace((unsigned char)*p)) - p++; - if ((x = strtol(p, &qq, 10)) == 0) - goto fail; - p = qq; - sc->wordlen = x; - while (isspace((unsigned char)*p)) - p++; - if (*p == '-') - p++; +/* --- @getflow@ --- * + * + * Arguments: @const char *p@ = pointer to string + * @const char **pp@ = where to store final pointer + * + * Returns: Flow control constant or @-1@ on error. + * + * Use: Parses a flow control setting. + */ - /* --- Pick out a parity designation --- */ +static int getflow(const char *p, const char **pp) +{ + const char *q; - while (isspace((unsigned char)*p)) - p++; for (q = p; isalpha((unsigned char)*q); q++) ; if (q == p) - goto fail; + return (-1); + if (pp) + *pp = q; if (strncmp(p, "none", q - p) == 0) - sc->parity = PARITY_NONE; - else if (strncmp(p, "odd", q - p) == 0) - sc->parity = PARITY_ODD; - else if (strncmp(p, "even", q - p) == 0) - sc->parity = PARITY_EVEN; + return (FLOW_NONE); + else if (strncmp(p, "soft", q - p) == 0 || + strncmp(p, "xon-xoff", q - p) == 0 || + strncmp(p, "xon/xoff", q - p) == 0 || + strncmp(p, "xonxoff", q - p) == 0) + return (FLOW_XONXOFF); + else if (strncmp(p, "hard", q - p) == 0 || + strncmp(p, "cts-rts", q - p) == 0 || + strncmp(p, "cts/rts", q - p) == 0 || + strncmp(p, "ctsrts", q - p) == 0 || + strncmp(p, "rts/cts", q - p) == 0 || + strncmp(p, "rts-cts", q - p) == 0 || + strncmp(p, "rtscts", q - p) == 0) + return (FLOW_RTSCTS); else - goto fail; - p = q; - while (isspace((unsigned char)*p)) - p++; - if (*p == '-') - p++; + return (-1); +} - /* --- Pick out a number of stop bits --- */ +/* --- @serial_parse@ --- * + * + * Arguments: @serial_config *sc@ = pointer to serial config structure + * @const char *k, *v@ = keyword and value pair + * + * Returns: Zero if OK, or @-1@ on error. + * + * Use: Parses a serial config string into something more + * reasonable. The config structure should have been + * initialized to something sensible (e.g., @SERIAL_INIT@) + * already. + */ - while (isspace((unsigned char)*p)) - p++; - if ((x = strtol(p, &qq, 10)) == 0) - goto fail; - p = qq; - sc->stopbits = x; - while (isspace((unsigned char)*p)) - p++; +int serial_parse(serial_config *sc, const char *k, const char *v) +{ + long x; + const char *q; + char *qq; - /* --- Done --- */ + if (strcmp(k, "baud") == 0 || strcmp(k, "bps") == 0) { + if (!v || (x = getbaud(v, &q)) < 0 || *q) + return (-1); + sc->baud = x; + } else if (strcmp(k, "data") == 0 || strcmp(k, "data-bits") == 0 || + strcmp(k, "databits") == 0 || strcmp(k, "data-len") == 0 || + strcmp(k, "datalen") == 0 || strcmp(k, "word") == 0 || + strcmp(k, "word-len") == 0 || strcmp(k, "wordlen") == 0) { + if (!v || (x = strtol(v, &qq, 10)) == 0 || *qq) + return (-1); + sc->wordlen = x; + } else if (strcmp(k, "parity") == 0) { + if (!v || (x = getparity(v, &q)) < 0 || *q) + return (-1); + sc->parity = x; + } else if (strcmp(k, "stop") == 0 || strcmp(k, "stop-bits") == 0 || + strcmp(k, "stopbits") == 0) { + if (!v || (x = strtol(v, &qq, 10)) == 0 || *qq) + return (-1); + sc->stopbits = x; + } else if (strcmp(k, "flow") == 0 || strcmp(k, "flow-control") == 0 || + strcmp(k, "flowcontrol") == 0) { + if (!v || (x = getflow(v, &q)) < 0 || *q) + return (-1); + sc->flow = x; + } else if (strcmp(k, "format") == 0) { + if (!v) + return (-1); + if ((x = strtol(v, &qq, 10)) == 0) + return (-1); + v = qq; + sc->wordlen = x; + if (*v == '-') + v++; + if ((x = getparity(v, &q)) < 0) + return (-1); + sc->parity = x; + v = q; + if (*v == '-') + v++; + if ((x = strtol(v, &qq, 10)) == 0) + return (-1); + v = qq; + sc->stopbits = x; + if (*v) + return (-1); + } else + return (-1); - if (*p) - goto fail; return (0); - -fail: - return (-1); } /*----- Test rig ----------------------------------------------------------*/ @@ -199,21 +255,29 @@ fail: #ifdef TEST_RIG #include +#include int main(int argc, char *argv[]) { int i; static const char *ptab[] = { "none", "odd", "even" }; + static const char *ftab[] = { "none", "xon/xoff", "rts/cts" }; for (i = 1; i < argc; i++) { serial_config sc = SERIAL_INIT; - - if (serial_parse(argv[i], &sc)) - printf("invalid serial configuration `%s'\n", argv[i]); - else { - printf("%lu %u-%s-%u\n", sc.baud, sc.wordlen, - ptab[sc.parity], sc.stopbits); + char *k, *v; + + for (k = strtok(argv[i], ";"); k; k = strtok(0, ";")) { + if ((v = strchr(k, '=')) != 0) + *v++ = 0; + if (serial_parse(&sc, k, v)) { + printf("invalid serial configuration `%s=%s'\n", k, v); + goto next; + } } + printf("%lu %u-%s-%u %s\n", sc.baud, sc.wordlen, + ptab[sc.parity], sc.stopbits, ftab[sc.flow]); + next:; } return (0); } diff --git a/serial.h b/serial.h index f514bda..bac1a96 100644 --- a/serial.h +++ b/serial.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: serial.h,v 1.1 2002/01/25 19:34:45 mdw Exp $ + * $Id: serial.h,v 1.2 2002/01/30 09:23:58 mdw Exp $ * * Common serial functionality * @@ -29,6 +29,11 @@ /*----- Revision history --------------------------------------------------* * * $Log: serial.h,v $ + * Revision 1.2 2002/01/30 09:23:58 mdw + * Follow new transport configuration interface. Add parameters for flow + * control. Break the format into separate parameters for independent + * configuration. + * * Revision 1.1 2002/01/25 19:34:45 mdw * Initial revision * @@ -51,21 +56,23 @@ typedef struct serial_config { unsigned long baud; /* Baud rate */ - unsigned wordlen; /* Word length */ - unsigned parity; /* Parity type (magic constant) */ - unsigned stopbits; /* Number of stop bits */ + unsigned char wordlen; /* Word length */ + unsigned char parity; /* Parity type (magic constant) */ + unsigned char stopbits; /* Number of stop bits */ + unsigned char flow; /* Flow control */ } serial_config; enum { PARITY_NONE, PARITY_ODD, PARITY_EVEN }; +enum { FLOW_NONE, FLOW_XONXOFF, FLOW_RTSCTS }; -#define SERIAL_INIT { 9600, 8, PARITY_NONE, 1 } +#define SERIAL_INIT { 9600, 8, PARITY_NONE, 1, FLOW_NONE } /*----- Functions provided ------------------------------------------------*/ /* --- @serial_parse@ --- * * - * Arguments: @const char *p@ = configuration string to parse - * @serial_config *sc@ = pointer to serial config structure + * Arguments: @serial_config *sc@ = pointer to serial config structure + * @const char *k, *v@ = keyword and value pair * * Returns: Zero if OK, or @-1@ on error. * @@ -75,7 +82,8 @@ enum { PARITY_NONE, PARITY_ODD, PARITY_EVEN }; * already. */ -extern int serial_parse(const char */*p*/, serial_config */*sc*/); +extern int serial_parse(serial_config */*sc*/, + const char */*k*/, const char */*v*/); /*----- That's all, folks -------------------------------------------------*/ -- 2.11.0