First, don't truncate long lines (at least when read from stdin).
Continue printing more cards as necessary.

Second, this fixes a crash on "invalid" input. Now you can generate a
series of random cards by running cat /dev/random | bcd

Index: bcd.c
===================================================================
RCS file: /cvs/src/games/bcd/bcd.c,v
retrieving revision 1.13
diff -u -p -r1.13 bcd.c
--- bcd.c       27 Oct 2009 23:59:24 -0000      1.13
+++ bcd.c       3 Nov 2014 23:02:11 -0000
@@ -110,44 +110,51 @@ u_short holes[256] = {
  */
 #define        bit(w,i)        ((w)&(1<<(i)))
 
-void   printcard(char *);
+void   printcard(char *, size_t);
+
+#define        COLUMNS 48
+
 
 int
 main(int argc, char *argv[])
 {
-       char cardline[80];
 
        /*
         * The original bcd prompts with a "%" when reading from stdin,
         * but this seems kind of silly.  So this one doesn't.
         */
-
        if (argc > 1) {
-               while (--argc)
-                       printcard(*++argv);
-       } else
-               while (fgets(cardline, sizeof(cardline), stdin))
-                       printcard(cardline);
+               while (--argc) {
+                       argv++;
+                       printcard(*argv, strlen(*argv));
+               }
+       } else {
+               char cardline[1024];
+               while (fgets(cardline, sizeof(cardline), stdin)) {
+                       char *p = cardline;
+                       size_t len = strlen(p);
+                       while (len > 0) {
+                               size_t amt = len > COLUMNS ? COLUMNS : len;
+                               printcard(p, amt);
+                               p += amt;
+                               len -= amt;
+                       }
+               }
+       }
        exit(0);
 }
 
-#define        COLUMNS 48
-
 void
-printcard(char *str)
+printcard(char *str, size_t len)
 {
        static const char rowchars[] = "   123456789";
        int     i, row;
-       char    *p;
-
-       /* ruthlessly remove newlines and truncate at 48 characters. */
-       str[strcspn(str, "\n")] = '\0';
+       char    *p, *end;
 
-       if (strlen(str) > COLUMNS)
-               str[COLUMNS] = '\0';
+       end = str + len;
 
        /* make string upper case. */
-       for (p = str; *p; ++p)
+       for (p = str; p < end; ++p)
                if (isascii(*p) && islower(*p))
                        *p = toupper(*p);
 
@@ -163,8 +170,8 @@ printcard(char *str)
         */
        p = str;
        putchar('/');
-       for (i = 1; *p; i++, p++)
-               if (holes[(int)*p])
+       for (i = 1; p < end; i++, p++)
+               if (holes[(unsigned char)*p])
                        putchar(*p);
                else
                        putchar(' ');
@@ -181,8 +188,8 @@ printcard(char *str)
         */
        for (row = 0; row <= 11; ++row) {
                putchar('|');
-               for (i = 0, p = str; *p; i++, p++) {
-                       if (bit(holes[(int)*p], 11 - row))
+               for (i = 0, p = str; p < end; i++, p++) {
+                       if (bit(holes[(unsigned char)*p], 11 - row))
                                putchar(']');
                        else
                                putchar(rowchars[row]);

Reply via email to