Index: usr.bin/morse/morse.6 =================================================================== --- usr.bin/morse/morse.6 +++ usr.bin/morse/morse.6 @@ -92,6 +92,11 @@ .Fl p or .Fl d . +.It Fl D +Decode morse output consisting of dots and dashes (as generated by using +the +.Fl s +option). .El .Pp The Index: usr.bin/morse/morse.c =================================================================== --- usr.bin/morse/morse.c +++ usr.bin/morse/morse.c @@ -59,6 +59,8 @@ /* Always use the speaker, let the open fail if -p is selected */ #define SPEAKER "/dev/speaker" +#define WHITESPACE " \t\n" + #ifdef SPEAKER #include #endif @@ -267,14 +269,11 @@ }; static void show(const char *), play(const char *), morse(char); +static void decode (char *), fdecode(FILE *); static void ttyout(const char *); static void sighandler(int); -#define GETOPTOPTS "c:d:ef:lsw:" -#define USAGE \ -"usage: morse [-els] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" - -static int pflag, lflag, sflag, eflag; +static int pflag, lflag, sflag, dflag, eflag; static int wpm = 20; /* effective words per minute */ static int cpm; /* effective words per minute between * characters */ @@ -293,11 +292,14 @@ #ifdef SPEAKER static tone_t sound; -#undef GETOPTOPTS -#define GETOPTOPTS "c:d:ef:lpsw:" -#undef USAGE +#define GETOPTOPTS "c:d:ef:lpsw:D" +#define USAGE \ +"usage: morse [-elpsD] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" +#else +#define GETOPTOPTS "c:d:ef:lsw:D" #define USAGE \ -"usage: morse [-elps] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" +"usage: morse [-elsD] [-d device] [-w speed] [-c speed] [-f frequency] [string ...]\n" + #endif static const struct morsetab *hightab; @@ -337,13 +339,16 @@ case 'w': wpm = atoi(optarg); break; + case 'D': + dflag = 1; + break; case '?': default: fputs(USAGE, stderr); exit(1); } - if (sflag && lflag) { - fputs("morse: only one of -l and -s allowed\n", stderr); + if ((sflag && lflag) || (sflag && dflag) || (lflag && dflag)) { + fputs("morse: only one of -l and -s and -D allowed\n", stderr); exit(1); } if ((pflag || device) && (sflag || lflag)) { @@ -421,7 +426,25 @@ if (lflag) printf("m"); - if (*argv) { + if (dflag) { + if (*argv) { + do { + p=strtok(*argv, " \t"); + if (p == NULL) + decode(*argv); + else { + while (p) { + decode(p); + p=strtok(NULL, " \t"); + } + } + } while (*++argv); + putchar('\n'); + } else { + fdecode(stdin); + } + } + else if (*argv) { do { for (p = *argv; *p; ++p) { if (eflag) @@ -577,6 +600,67 @@ usleep(duration); } +void +fdecode(FILE *stream) +{ + char *n, *p, *s; + char buf[BUFSIZ]; + + s=buf; + while (fgets(s, BUFSIZ - (s - buf), stdin)) { + p=buf; + + while (*p && isblank(*p)) + p++; + while (*p && isspace(*p)) { + p++; + putchar (' '); + } + while (*p) { + n=strpbrk(p, WHITESPACE); + if (n == NULL) { + /* The token was interrupted at the end + * of the buffer. Shift it to the begin + * of the buffer. + */ + for (s=buf; *p; *s++ = *p++) + ; + } else { + *n='\0'; + n++; + decode(p); + p=n; + } + } + } + putchar('\n'); +} + +void +decode(char *p) +{ + char c; + const struct morsetab *m; + + c = ' '; + for (m = mtab; m != NULL && m->inchar != '\0'; m++) { + if (strcmp(m->morse, p) == 0) { + c = m->inchar; + break; + } + } + + if (c == ' ') + for (m = hightab; m != NULL && m->inchar != '\0'; m++) { + if (strcmp(m->morse, p) == 0) { + c = m->inchar; + break; + } + } + + putchar(c); +} + static void sighandler(int signo) {