Cat

June 8, 2012

This is easy, except that we have no way to implement the buffered input, so we ignore any -u argument that might be present. Here’s the program:

#! /usr/bin/scheme --script

(define (do-file file-name)
  (let ((p (if (string=? file-name "-")
               (current-input-port)
               (open-input-file file-name))))
    (do ((c (read-char p) (read-char p)))
        ((eof-object? c))
      (display c))
    (close-input-port p)))

(let ((args (if (and (pair? (cdr (command-line)))
                     (string=? (cadr (command-line)) "-u"))
                (cddr (command-line))
                (cdr (command-line)))))
  (if (null? args)
      (do-file "-")
      (do ((args args (cdr args)))
          ((null? args))
        (do-file (car args)))))

The header line and the (command-line) function are non-standard Scheme and are unique to Chez Scheme, though all Scheme systems provide something similar; (command-line) returns the command line by which the program was called, including the name of the program in its car. Variable args is set to the list of file name arguments passed on the command line, an empty argument list is handled specially, and function do-file processes a single file after setting the input port appropriately.

You can see the program at http://programmingpraxis.codepad.org/HS4bHJFl.

Pages: 1 2

2 Responses to “Cat”

  1. My Haskell solution. Ignores the “-u” switch.


    import System.Environment
    import System.IO
    import Control.Exception

    parseCmd :: [String] -> IO [Handle]
    parseCmd [] = return []
    parseCmd ["-"] = return [stdin]
    parseCmd ("-u":xs) = parseCmd xs
    parseCmd xs = mapM (`openFile` ReadMode) xs

    main :: IO ()
    main = do
    args hGetContents h >>= putStr))

  2. Ok, something went wrong while posting. Let’s try again.

    import System.Environment
    import System.IO
    import Control.Exception
    
    
    parseCmd :: [String] -> IO [Handle]
    parseCmd []        = return []
    parseCmd ["-"]     = return [stdin]
    parseCmd ("-u":xs) = parseCmd xs
    parseCmd xs        = mapM (`openFile` ReadMode) xs
    
    main :: IO ()
    main = do
      args <- getArgs
      bracket (parseCmd args) (mapM_ hClose)
              (mapM_ (\h -> hGetContents h >>= putStr))
    

Leave a comment