Version 0 of gnuerr

Updated 2006-08-03 10:38:56

gnuerr

Usually, when an error is to be signalled, error command is to do the job. However, what it prints to standard error when used in scripts doesn't conform to Unix conventions, which require an error message to be preceded by the program name and a colon, e. g.:

 foo: unrecognized option `--bar'

 bar: file: No such file or directory

Here is suggested a simple gnuerr command to print error messages, similar to the GNU C Library error function. Of course, it's only useful in applications which aren't interactive (or which support non-interactive mode at least.) That is, in CLI applications.

Variable
program-short-name

This variable holds the tail element of the program path, argv0, i. e.:

 file tail $::argv0

It's put before the error message itself by the following procedures.

Procedure
gnuerr ?-exit returnCode?
                       ''formatString'' ?''arg'' ''arg'' ''...''?

Prints an error message to stderr. The message consists of the program name, followed by a colon, a space, and the result of applying format to the formatString and the remaining arguments. If the message to be printed contains embedded newlines, each line of the message will be prepended by the program name on output.

If the returnCode is given and non-zero, the procedure pass it to exit after the message is printed.

TODO List:

  • parse errorCode (if requested) and print POSIX error message after the message printed;
  • something like error_at_line could be useful as well.
 ### gnuerr.tcl  -*- Tcl -*-
 ## The following code is in public domain.

 ### Code:

 namespace eval ::gnuerr {
     variable program-short-name \
         [ file tail $::argv0 ]
     namespace export gnuerr
 }

 proc ::gnuerr::msg { formatString args } {
     variable program-short-name
     set s [ uplevel \#0 [ list ::format $formatString ] $args ]
     set l [ split $s "\n" ]
     if { ! [ string length [ lindex $l end ] ] } {
         set l [ lrange $l 0 end-1 ]
     }
     set message ""
     foreach s $l {
         append message "${program-short-name}: $s\n"
     }
     ## .
     puts -nonewline stderr $message
 }

 proc ::gnuerr::gnuerr { args } {
     if { [ llength $args ] < 1 } {
         error [ format "wrong # args: should be \"gnuerr %s\"" \
                     "?-exit returnCode? formatString ?arg arg ...?" ]
     } elseif { ! [ string equal "-exit" [ lindex $args 0 ] ] } {
         set exit 0
     } elseif { [ llength $args ] < 2 } {
         error "expected argument after \"-exit\""
     } elseif { [ set exit [ lindex $args 1 ]
                  catch { incr exit 0 } ] } {
         error "expected integer but got \"$exit\""
     } else {
         set args [ lrange $args 2 end ]
     }
     eval msg $args
     ## .
     if { $exit } {
         exit $exit
     }
 }

 ### gnuerr.tcl ends here

Category Package