System: unroff version 1.0 Patch #: 1 Priority: high Required-Distribution: source Description: scm/troff.scm: o No longer expands number registers and strings when reading Scheme code following ".ig ##" o .el followed by \{\ was parsed incorrectly o .el failed if negation operator was used in corresponding .ie o Escape sequences (such as \w) inside arguments to .nr request are now treated correctly scm/html/common.scm: o No longer complains about tab characters inside comments scm/html/man.scm: o .sp and .ti caused unroff to terminate with a Scheme error when invoked without argument src/*.[hc]: o 8-bit chars were sign extended when passed to isspace() in several places (added cast to unsigned char) doc/unroff.1: o Updated explanation of ".ig ##" request Fix: From rn, say "| patch -p -N -d DIR", where DIR is the top of your unroff source or binary directory tree. Outside of rn, say "cd DIR; patch -p -N > are sent to the current output file. - The text is subject to normal string and number register expansion. Example: when translating to the Hypertext Markup Language, the construct could be used to emit literal HTML code like this: --- 526,531 ---- *** 1.20 1995/04/12 13:57:57 --- scm/troff.scm 1995/06/02 11:55:42 *************** *** 262,273 **** (defrequest 'ig (lambda (ig delim) (define (copy-exec stop what) ! (let loop ((s (read-line-expand))) (cond ((eof-object? s) (warn "end-of-stream during ~a" what)) ((not (string=? s stop)) (emit s) ! (loop (read-line-expand)))))) (cond ((string=? delim "##") (with-output-to-stream '[##] --- 262,273 ---- (defrequest 'ig (lambda (ig delim) (define (copy-exec stop what) ! (let loop ((s (read-line))) (cond ((eof-object? s) (warn "end-of-stream during ~a" what)) ((not (string=? s stop)) (emit s) ! (loop (read-line)))))) (cond ((string=? delim "##") (with-output-to-stream '[##] *************** *** 397,403 **** (else (unread-line (hack-if-argument rest)))) (if (string=? request "ie") ! (list-push! if-stack doit?)) "")) ;; Some people like to write .if requests such as --- 397,403 ---- (else (unread-line (hack-if-argument rest)))) (if (string=? request "ie") ! (list-push! if-stack (not (eq? neg? doit?)))) "")) ;; Some people like to write .if requests such as *************** *** 417,425 **** (cond ((null? if-stack) (warn ".el without matching .ie request")) (else (unread-line (hack-if-argument rest)) - (if (car if-stack) (skip-group)) (list-pop! if-stack))) "")) --- 417,428 ---- (cond ((null? if-stack) (warn ".el without matching .ie request")) + ((car if-stack) + (unread-line (concat rest #\newline)) + (skip-group) + (list-pop! if-stack)) (else (unread-line (hack-if-argument rest)) (list-pop! if-stack))) "")) *************** *** 438,447 **** ((eqv? val "") (warn "missing value for .nr")) (else ! (let ((old (table-lookup numreg-table name)) ! (n (parse-expression val #f #\u)) ! (add? (string-prune-left val "+" #f)) ! (i (if (eqv? incr "") #f (parse-expression incr #f #\u)))) (cond ((not n) "") (old --- 441,453 ---- ((eqv? val "") (warn "missing value for .nr")) (else ! (let* ((old (table-lookup numreg-table name)) ! (v (parse val)) ! (n (parse-expression v #f #\u)) ! (add? (string-prune-left v "+" #f)) ! (i (if (eqv? incr "") ! #f ! (parse-expression (parse incr) #f #\u)))) (cond ((not n) "") (old *** 1.17 1995/04/09 13:41:15 --- scm/html/common.scm 1995/06/02 11:39:58 *************** *** 534,542 **** (defescape #\" (lambda (_ x) ! (let ((c (string-prune-right x "\n" x))) (if (and (not (eqv? c "")) (not (stream-buffer? (output-stream)))) (emit "\n")) #\newline))) --- 534,544 ---- (defescape #\" (lambda (_ x) ! (let ((c (string-prune-right x "\n" x)) ! (old (defchar #\tab #f))) (if (and (not (eqv? c "")) (not (stream-buffer? (output-stream)))) (emit "\n")) + (defchar #\tab old) #\newline))) *** 1.16 1995/04/09 13:41:15 --- scm/html/man.scm 1995/06/04 11:41:44 *************** *** 281,297 **** (defrequest 'sp (let ((orig (requestdef 'sp))) ! (lambda args ! (concat (hang-para #f) (apply orig args))))) (defrequest 'bp (lambda _ (hang-para #f))) (defrequest 'ti (let ((orig (requestdef 'ti))) ! (lambda args ! (concat (hang-para #f) (apply orig args))))) ! ;;; Kuldge: Suppress
immediately after `hang-para' to avoid excessive ;;; white space (defrequest 'br --- 281,297 ---- (defrequest 'sp (let ((orig (requestdef 'sp))) ! (lambda (sp num) ! (concat (hang-para #f) (orig sp num))))) (defrequest 'bp (lambda _ (hang-para #f))) (defrequest 'ti (let ((orig (requestdef 'ti))) ! (lambda (ti num) ! (concat (hang-para #f) (orig ti num))))) ! ;;; Kludge: Suppress
immediately after `hang-para' to avoid excessive ;;; white space (defrequest 'br *** 1.11 1995/04/12 13:58:15 --- src/error.c 1995/06/02 11:29:22 *************** *** 65,71 **** bp = buffer_new(0); buffer_clear(bp); for ( ; len > 0; len--, s++) { ! if (isprint(*s) || *s == ' ') { buffer_putc(bp, *s); } else { buffer_putc(bp, '\\'); --- 65,71 ---- bp = buffer_new(0); buffer_clear(bp); for ( ; len > 0; len--, s++) { ! if (isprint(UCHAR(*s)) || *s == ' ') { buffer_putc(bp, *s); } else { buffer_putc(bp, '\\'); *** 1.20 1995/04/28 11:17:39 --- src/parse.c 1995/06/02 11:30:28 *************** *** 136,143 **** p++; break; } ! } else if (isspace(*p)) { /* kill space before comment */ ! for (s = p+1; s < ep-1 && isspace(*s); s++) ; if (s < ep-1 && *s == escape && s[1] == '"') p = s; --- 136,143 ---- p++; break; } ! } else if (isspace(UCHAR(*p))) { /* kill space before comment */ ! for (s = p+1; s < ep-1 && isspace(UCHAR(*s)); s++) ; if (s < ep-1 && *s == escape && s[1] == '"') p = s; *************** *** 230,236 **** check_arg((q = p++) == ep); len = 1; if (spec == ARG_SIZE && q < ep-1 && *q > '0' && *q < '4' ! && isdigit(*p)) { len++, p++; } break; --- 230,236 ---- check_arg((q = p++) == ep); len = 1; if (spec == ARG_SIZE && q < ep-1 && *q > '0' && *q < '4' ! && isdigit(UCHAR(*p))) { len++, p++; } break; *************** *** 351,357 **** ; start = p; ! for ( ; p < ep && !isspace(*p); p++) if (compatible && p == start+2) break; if ((reqlen = p - start) == 0) /* just a period */ --- 351,357 ---- ; start = p; ! for ( ; p < ep && !isspace(UCHAR(*p)); p++) if (compatible && p == start+2) break; if ((reqlen = p - start) == 0) /* just a period */ *************** *** 384,390 **** args_clear(); args_add(Make_String(start, reqlen)); for (num = 1; ; num++) { ! for ( ; p < ep && isspace(*p); p++) ; if (p >= ep) break; --- 384,390 ---- args_clear(); args_add(Make_String(start, reqlen)); for (num = 1; ; num++) { ! for ( ; p < ep && isspace(UCHAR(*p)); p++) ; if (p >= ep) break; *************** *** 400,406 **** */ break; } ! if (!quote && isspace(*p) && (macro || num < maxargs)) break; if (quote && *p == '"') { if (p < ep-1 && p[1] == '"') /* turn "" into " */ --- 400,406 ---- */ break; } ! if (!quote && isspace(UCHAR(*p)) && (macro || num < maxargs)) break; if (quote && *p == '"') { if (p < ep-1 && p[1] == '"') /* turn "" into " */ *** 1.18 1995/04/12 13:58:15 --- src/prim.c 1995/06/02 11:30:41 *************** *** 331,341 **** Check_Type(str, T_String); p = STRING(str)->data, ep = p + STRING(str)->size; ! for ( ; p < ep && isspace(*p); p++) ; if (p == ep) return False; ! for (q = p; p < ep && !isspace(*p); p++) ; if (p == ep) return True; --- 331,341 ---- Check_Type(str, T_String); p = STRING(str)->data, ep = p + STRING(str)->size; ! for ( ; p < ep && isspace(UCHAR(*p)); p++) ; if (p == ep) return False; ! for (q = p; p < ep && !isspace(UCHAR(*p)); p++) ; if (p == ep) return True; *** 1.16 1995/04/26 11:29:24 --- src/unroff.h 1995/06/02 11:29:03 *************** *** 43,48 **** --- 43,55 ---- extern void Load_Source_Port(Object); + /* Used for passing a `char' to a function that takes an `int' argument, + * such as isspace(). Maybe I should have used `unsigned char' rather + * than `char' in the first place... + */ + #define UCHAR(c) ((unsigned char)(c)) + + #include "config.h" #include "args.h" #include "buffer.h"