Re: Factor

Factor: the language, the theory, and the practice.

copy

Thursday, February 2, 2012

#command-line #files

I’ve used Factor to build several common unix programs including cat, fortune, wc, and others.

Today, I wanted to show how to build the cp (“copy”) program using the simple file manipulation words. If we look at the man page, we can see that its usage is two-fold:

  1. Copy several source files to a destination directory
  2. Copy a source file to a destination file or directory

We can make a nice usage string to display if the arguments are not correct:

: usage ( -- )
    "Usage: copy source ... target" print ;

We can implement the first usage, copy-to-dir, by checking to see that the destination is a directory before calling copy-files-into, or printing the usage if it is not:

: copy-to-dir ( args -- )
    dup last file-info directory?
    [ unclip-last copy-files-into ] [ drop usage ] if ;

The second usage, copy-to-file, first checks if the destination exists and is a directory (if so calling our copy-to-dir word), otherwise calling copy-file:

: copy-to-file ( args -- )
    dup last { [ exists? ] [ file-info directory? ] } 1&&
    [ copy-to-dir ] [ first2 copy-file ] if ;

Putting it all together, we can implement our program by checking the number of arguments and assuming the two-argument version is copy-to-file and more arguments are copy-to-dir (anything less gets the usage):

: run-copy ( -- )
    command-line get dup length {
        { [ dup 2 > ] [ drop copy-to-dir  ] }
        { [ dup 2 = ] [ drop copy-to-file ] }
        [ 2drop usage ]
    } cond ;

MAIN: run-copy

The code for this is on my GitHub.