aboutsummaryrefslogtreecommitdiff
path: root/pkg/lists
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/lists
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'pkg/lists')
-rw-r--r--pkg/lists/README1
-rw-r--r--pkg/lists/Revisions52
-rw-r--r--pkg/lists/average.cl56
-rw-r--r--pkg/lists/average.par10
-rw-r--r--pkg/lists/columns.par4
-rw-r--r--pkg/lists/columns.x65
-rw-r--r--pkg/lists/doc/Lcalc.hlp539
-rw-r--r--pkg/lists/doc/Lintran.spc.hlp60
-rw-r--r--pkg/lists/doc/Lists.hlp569
-rw-r--r--pkg/lists/doc/average.hlp49
-rw-r--r--pkg/lists/doc/columns.hlp38
-rw-r--r--pkg/lists/doc/lintran.hlp103
-rw-r--r--pkg/lists/doc/raverage.hlp110
-rw-r--r--pkg/lists/doc/rgcursor.hlp94
-rw-r--r--pkg/lists/doc/rimcursor.hlp270
-rw-r--r--pkg/lists/doc/table.hlp43
-rw-r--r--pkg/lists/doc/tokens.hlp55
-rw-r--r--pkg/lists/doc/unique.hlp27
-rw-r--r--pkg/lists/doc/words.hlp22
-rw-r--r--pkg/lists/filter.cl6
-rw-r--r--pkg/lists/lintran.par12
-rw-r--r--pkg/lists/lintran.x370
-rw-r--r--pkg/lists/lists.cl20
-rw-r--r--pkg/lists/lists.hd14
-rw-r--r--pkg/lists/lists.men10
-rw-r--r--pkg/lists/lists.par4
-rw-r--r--pkg/lists/mkpkg32
-rw-r--r--pkg/lists/raverage.cl146
-rw-r--r--pkg/lists/rgcursor.x27
-rw-r--r--pkg/lists/rimcursor.par5
-rw-r--r--pkg/lists/rimcursor.x191
-rw-r--r--pkg/lists/table.par5
-rw-r--r--pkg/lists/table.x111
-rw-r--r--pkg/lists/tokens.par5
-rw-r--r--pkg/lists/tokens.x140
-rw-r--r--pkg/lists/unique.par1
-rw-r--r--pkg/lists/unique.x46
-rw-r--r--pkg/lists/words.par1
-rw-r--r--pkg/lists/words.x44
-rw-r--r--pkg/lists/x_lists.x12
40 files changed, 3369 insertions, 0 deletions
diff --git a/pkg/lists/README b/pkg/lists/README
new file mode 100644
index 00000000..fdf7e991
--- /dev/null
+++ b/pkg/lists/README
@@ -0,0 +1 @@
+LISTS -- Tools for operating upon tables stored in text form.
diff --git a/pkg/lists/Revisions b/pkg/lists/Revisions
new file mode 100644
index 00000000..dc65a913
--- /dev/null
+++ b/pkg/lists/Revisions
@@ -0,0 +1,52 @@
+.help revisions Jun88 pkg.lists
+.nf
+
+lintran.x
+ Modified to store parameter structure as doubles to avoid round-off
+ issues (9/4/12)
+
+=====
+V2.13
+=====
+
+raverage.cl +
+doc/raverage.hlp +
+lists.cl
+lists.men
+lists.hd
+ Added a new running average task. (5/4/07, Valdes)
+
+=======
+V2.12.3
+=======
+
+=====
+V2.12
+=====
+
+doc/Lcalc.hlp
+doc/Lcalc.hlp
+doc/Lists.hlp
+doc/unique.hlp
+doc/average.hlp
+ Fixed various formatting problems in the lists package help files.
+ (19/09/01, Davis)
+
+rimcursor.par
+rimcursor.x
+doc/rimcursor.hlp
+ Added the parameters wxformat and wyformat to the rimcursor task.
+ These default formats take precedence over the formats stored in the
+ WCS in the image header and the default format for all values
+ of the wcs parameter. (Davis 9/3/92)
+
+columns.x
+ The columns task has been reinstalled. The default value of
+ outroot was changed, source code cleaned up and manual page
+ updated. (ShJ 12-NOV-88)
+
+Davis, October 5, 1988
+ 1. I replaced the data_value ** 2 and sum ** 2 constructs in the
+ average script to get around a SUN problem with raising 0.0 to any
+ power. This is probably good programming practice in any case.
+.endhelp
diff --git a/pkg/lists/average.cl b/pkg/lists/average.cl
new file mode 100644
index 00000000..d6d12b6e
--- /dev/null
+++ b/pkg/lists/average.cl
@@ -0,0 +1,56 @@
+#{ AVERAGE -- Compute the average and standard deviation of a list of numbers.
+# Numeric input is via the standard input (one number per line). The mean,
+# sigma, and number of samples are written to the standard output.
+#
+# By default (Average called with no arguments), the sample is taken
+# to be the set of numbers in the standard input when Average is run.
+# Additional points can be added to or deleted from the sample by
+# rerunning Average with one of the following arguments:
+#
+# add - add points to the sample, recalculate mean and sigma
+# sub - subtract points from the sample
+
+
+{
+ if ($nargs == 0) # if no arguments, don't query
+ opstring = "new_sample"
+ else
+ opstring = option # get parameter "option"
+
+
+ if (opstring == "add") # add, subtract, or start over?
+ addsub_flag = 1
+ else if (opstring == "sub" || opstring == "subtract")
+ addsub_flag = -1
+ else { # new sample (default)
+ addsub_flag = 1
+ n = 0 # number of points in sample
+ sum = 0
+ sumsqrs = 0
+ }
+
+
+ # Process data; print mean, sigma, and the sample size on
+ # the standard output.
+
+ while (scan (data_value) != EOF)
+ if (nscan() == 1 && data_value != INDEF) {
+ n += addsub_flag
+ sum += addsub_flag * data_value
+ sumsqrs += addsub_flag * data_value * data_value
+ }
+
+ if (n <= 0)
+ print ("INDEF ", "INDEF ", n)
+ else if (n == 1)
+ print (sum, "INDEF ", 1)
+ else {
+ mean = sum / n
+ variance = (n * sumsqrs - sum * sum) / (n * (n-1))
+ if (variance < 0) # possible with roundoff error
+ sigma = 0.0
+ else
+ sigma = sqrt (variance)
+ print (mean, sigma, n)
+ }
+}
diff --git a/pkg/lists/average.par b/pkg/lists/average.par
new file mode 100644
index 00000000..d5f6ec17
--- /dev/null
+++ b/pkg/lists/average.par
@@ -0,0 +1,10 @@
+option,s,a,new_sample,,,'Type of sample (new_sample, add, subtract)'
+opstring,s,h
+addsub_flag,i,h
+data_value,r,h
+n,i,h
+sum,r,h
+sumsqrs,r,h
+mean,r,h
+variance,r,h
+sigma,r,h
diff --git a/pkg/lists/columns.par b/pkg/lists/columns.par
new file mode 100644
index 00000000..cc4f6758
--- /dev/null
+++ b/pkg/lists/columns.par
@@ -0,0 +1,4 @@
+# Parameters for columns task
+filename,s,a,,,,Name of the input table file
+numcols,i,a,,,,Number of columns
+outroot,s,h,"col.",,,Root name of the output column files
diff --git a/pkg/lists/columns.x b/pkg/lists/columns.x
new file mode 100644
index 00000000..c5e44abc
--- /dev/null
+++ b/pkg/lists/columns.x
@@ -0,0 +1,65 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+define MAX_FILES 50
+
+# COLUMNS -- Convert a multicolumn file into a series of single column files.
+# One output file `columns.n' is produced for each column in the input file.
+#
+# usage: COLUMNS input_file ncols
+#
+# This routine was originally written to allow SDAS to treat multicolumn
+# tables as simple CL lists. Each column in the table is referenced in
+# SDAS by a different parameter, pointing in the .par file to
+# a different list.
+
+procedure t_columns()
+
+int numcols, infd, nchar, nfile, ip
+pointer sp, fname, ofile, oroot, line, word, fnum, ofd
+int clgeti(), open(), getline(), itoc(), ctowrd()
+
+begin
+ call smark (sp)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+ call salloc (ofile, SZ_FNAME, TY_CHAR)
+ call salloc (oroot, SZ_FNAME, TY_CHAR)
+ call salloc (line, SZ_LINE, TY_CHAR)
+ call salloc (word, SZ_LINE, TY_CHAR)
+ call salloc (fnum, SZ_FNAME, TY_CHAR)
+ call salloc (ofd, MAX_FILES, TY_INT)
+
+ # Get the number of columns and the input file name
+ call clgstr ("filename", Memc[fname], SZ_FNAME)
+ numcols = clgeti ("numcols")
+ if (numcols > MAX_FILES)
+ call error (1, "too many files (columns)")
+ call clgstr ("outroot", Memc[oroot], SZ_FNAME)
+
+ # Open all the files
+ infd = open (Memc[fname], READ_ONLY, TEXT_FILE)
+ for (nfile=1; nfile <= numcols; nfile=nfile+1) {
+ nchar = itoc (nfile, Memc[fnum], 2)
+ call strcpy (Memc[oroot], Memc[ofile], SZ_FNAME)
+ call strcat (Memc[fnum], Memc[ofile], SZ_FNAME)
+ Memi[ofd+nfile-1] = open (Memc[ofile], NEW_FILE, TEXT_FILE)
+ }
+
+ # Separate each line of the input file
+ while (getline (infd, Memc[line]) != EOF) {
+ if ((Memc[line] != '#') && (Memc[line] != '\n')) {
+ ip = 1
+ for (nfile=1; nfile <= numcols; nfile=nfile+1) {
+ nchar = ctowrd (Memc[line], ip, Memc[word], SZ_LINE)
+ call strcat ("\n", Memc[word], SZ_LINE)
+ call putline (Memi[ofd+nfile-1], Memc[word])
+ }
+ }
+ }
+
+ # Close the files.
+ call close (infd)
+ for (nfile=1; nfile <= numcols; nfile=nfile+1)
+ call close (Memi[ofd+nfile-1])
+
+ call sfree (sp)
+end
diff --git a/pkg/lists/doc/Lcalc.hlp b/pkg/lists/doc/Lcalc.hlp
new file mode 100644
index 00000000..a21cf8b8
--- /dev/null
+++ b/pkg/lists/doc/Lcalc.hlp
@@ -0,0 +1,539 @@
+.help lcalc Apr84 "List Calculator"
+.nh
+Introduction
+
+ The list calculator performs general arithmetic, string, and
+conditional operations upon lists. Examples of such operations include
+.ls 4
+.ls o
+General filtering of lists, i.e., conditionally pass or stop records
+within a list.
+.le
+.ls o
+Rearranging the fields of a list.
+.le
+.ls o
+Extracting fields from a list.
+.le
+.ls o
+Merging lists.
+.le
+.ls o
+Arithmetic or string operations upon lists.
+.le
+.le
+
+A \fBlist\fR is a text file consisting of a sequence of \fBrecords\fR.
+Whitespace normally delimits the fields of a record; newline normally
+delimits a record. There may be an arbitrary number of fields within a
+record, and records within a list. A record may span several lines of
+text if a special delimiter is used. Blank lines and comment lines are
+passed on to the output but are otherwise ignored.
+
+The input language of the list calculator is optimized to provide a
+concise notation for expressing the types of operations most commonly
+performed upon lists. Operations which cannot be specified by this
+somewhat specialized language can easily be programmed as CL scripts.
+
+.nh
+Lists
+
+ Input may consist of one or more logical input lists. Multiple input
+lists are by default read simultaneously as discreet lists; they may
+optionally be concatenated into a single logical list.
+A single list is always generated as output. Multiple input lists
+are referred to in expressions as "lN", i.e., "l1", "l2", etc.
+If multiple discreet input lists are used, the output list will be
+truncated to the length of the shortest input list.
+
+.nh
+Records
+
+ The list calculator breaks each list into a sequence of records.
+Each record has the following attributes:
+
+.nf
+ record number
+ record length
+ number of fields
+.fi
+
+If the record delimiter is other than newline, newline is treated as
+whitespace. Records are numbered starting at 1. Record number BOL may
+be used to conditionally execute code before processing a list. Record
+number EOL is matched only at the end of the list.
+
+.nh
+Fields
+
+ The list calculator breaks each record into a sequence of fields.
+Each field has the following attributes:
+
+.nf
+ field number
+ field width (nchars in input record)
+ datatype
+ number of significant digits, if a number
+.fi
+
+The "current record" may be thought of as an array F of fields.
+The individual fields may be referenced in expressions in either of two
+ways. If a single field is to be referenced, the field may be referred
+to as the variable fN, e.g., "f1", "f2", and so on. If multiple
+input lists are in use, the notation "li.fj" must be used instead.
+Sets of fields may be referenced as sections of the array F;
+a \fBsection\fR is an operand of type string, and may not be used
+in arithmetic expressions. The entire record is most simply referred
+to as the string R. The section notation may also be used to refer
+to substrings of string type operands, and is discussed in a later section.
+
+.nh
+Calling Sequence
+
+ The principal operands to \fBlcalc\fR are the list template and
+the program to be executed. An additional set of positional arguments
+may be given; these are passed on to the program and are not used by
+\fBlcalc\fR itself. A number of hidden parameters are available to
+modify the behavior of the program.
+
+ lcalc (list, program [, p1,...,p9])
+
+.nh
+Parameters
+.ls 4
+.ls lists
+A filename template specifying the list files to be processed. Not used
+if the standard input is redirected.
+.le
+.ls program
+Either the explicit \fBlcalc\fR program to be run, or if the first character
+is an @, the name of a file containing the program.
+.le
+.ls p1 - p9
+Optional program parameters, referred to in the program as "$1", "$2", etc.
+.le
+.ls concatenate = no
+Treat multiple input lists independently (concatenate = no) or concatenate
+all input lists to form a single list.
+.le
+.ls field_delim = " \t"
+A set of characters, any \fIone\fR of which will delimit the fields of an input
+record. The default field delimiters are blank and tab (denoted \t).
+.le
+.ls record_delim = "$"
+The \fIpattern\fR which delimits input records. All of the usual pattern
+matching meta-characters are recognized. The default is "$", meaning that
+end of line delimits input records (each record is a line of the input list).
+Special record delimiters may be used to process multiline records.
+.le
+.ls ofield_delim = "in_field_delim"
+The output field delimiter, inserted by the list calculator in output records
+to delimit fields. The string "in_field_delim" signals that the first input
+field delimiter character is to be used.
+.le
+.ls orecord_delim = "in_record_delim"
+The output record delimiter, used to delimit output records. The default
+action is to use the string (not pattern) which delimited the input record.
+.le
+.ls comments = yes
+Pass comment lines and blank lines on to the output list.
+.le
+.le
+
+.nh
+Statements
+
+ A list transformation is specified by a program consisting of a
+sequence of statements. The program may be input either directly on
+the command line as a string, or in a file. Statements may be delimited
+by either semicolon or newline.
+
+.nf
+ prog : stmt
+ | prog stmt
+ ;
+
+ stmt : assign eost
+ | print eost
+ ;
+
+ eost : '\n'
+ | ';'
+ ;
+.fi
+
+There are two types of statements, assignment statements and print
+statements. The \fBassignment\fR statements may be used to set or modify
+the contents of an internal register. Registers are created and initialized
+to zero or to the null string when first referenced in an assignment statement.
+The usual modify and replace assignment statements "+=", "//=", etc. are
+recognized.
+
+.nf
+ assign : IDENT '=' expr
+ | IDENT OPEQ expr
+ ;
+
+ print : expr
+ | expr '?'
+ | expr '?' expr
+ ;
+.fi
+
+The \fBprint\fR statement is used to generate output. In its simplest
+form the print statement is an expression (e.g., "f5"); the value of the
+expression is computed and output as the next field of the output record.
+
+As a simple example, suppose we wish to swap fields 2 and 3 of a three field
+list, dropping field 1 (any additional fields will be discarded):
+
+ lcalc list, "f3,f2"
+
+.nh
+Expressions
+
+ The power of the list calculator derives principally from its ability
+to evaluate complex expressions. The operands of an expression may be
+fields, registers, command line arguments, functions, constants, or
+expressions. The datatype of an expression may be boolean, integer, real,
+or string. Conditional expressions may be used to select or reject entire
+records, or to conditionally format the fields of output records.
+
+The standard set of operators are supported. Expressions are evaluated
+using the standard operator precedences and associativities. The following
+operators are recognized:
+
+
+.nf
+binary operators:
+
+ + - * / ** arithmetic
+ < <= > >= == != @ comparison
+ && || boolean and, or
+ // string concatenation
+
+
+unary operators:
+
+ ! - @
+.fi
+
+The only unconventional operator is the string matching operator @,
+used to determine if a string matches a pattern. Usage is as follows:
+
+.nf
+ string @ pattern
+or
+ @ pattern
+.fi
+
+The expression evaluates to true if the pattern can be matched. If no
+string is given, the entire record is searched.
+
+The expression syntax recognized by the list calculator is defined in
+the figure below.
+
+
+.nf
+ expr : primary
+ | expr ',' opnl expr
+ | '(' expr ')'
+ ;
+
+ primary : IDENT
+ | CONSTANT
+ | primary BINOP opnl primary
+ | UNOP primary
+ | primary '?' primary ':' primary
+ | IDENT '(' arglist ')'
+ | section
+ | '(' primary ')'
+ ;
+
+ section : IDENT '[' flist ']'
+ ;
+
+ flist : # Empty
+ | fields
+ | flist ',' fields
+ ;
+
+ fields : primary
+ | primary ':'
+ | primary ':' ':' primary
+ | primary ':' primary
+ | primary ':' primary ':' primary
+ | '*'
+ | '-' '*'
+ | '-' '*' ':' primary
+ ;
+.fi
+
+.nh
+Sections
+
+ The section notation is used to extract substrings from string type
+variables. If the variable referenced is F, an array of strings, then
+the section indexes the fields of the record; the specified fields are
+concatenated to produce the output string. If the variable is a string
+variable, an array of characters, then the section specifies a set of
+substrings to be concatenated.
+
+For example, to extract the first three characters of the string
+variable "s":
+
+ s[1:3]
+
+To extract characters 4 through the end of the string:
+
+ s[4:]
+
+To reverse the order of the characters in the string:
+
+ s[-*]
+
+To extract the first field of the record:
+
+ f[1]
+
+To extract all fields, any of the following would do (F is the array of
+field strings, whereas R is the entire record as a string):
+
+ r, r[*], r[1:], f, f[*], f[1:]
+
+To refer to all fields in reverse order:
+
+ f[-*]
+
+To specify fields 3 through 5:
+
+ f[3:5]
+
+To specify fields 3, 5, and 7 through 10:
+
+ f[3,5,7:10]
+
+If multiple input lists are in use, the notation "r1", "r2", etc. should
+be used instead.
+
+.nh
+Intrinsic Functions
+
+ All of the standard intrinsic functions are recognized, plus a few
+special intrinsic functions.
+
+.nf
+ abs exp log min real str
+ atan2 int log10 mod sin tan
+ cos len max nint sqrt type
+.fi
+
+Certain of these functions deserve further mention:
+.ls 4
+.ls len (expr)
+Returns the length of an array or string, e.g., "len(f)" is the number
+of fields in the current record, and "len(f2)" is the number of chars in
+field 2.
+.le
+.ls str (expr)
+Converts the argument into an operand of type string.
+.le
+.ls type (expr)
+Returns the datatype of the argument. Legal values are "b", "i", "r",
+and "s". The string type is the catchall.
+.le
+.le
+
+.nh
+Variables
+
+ The types of variables implemented in the list calculator are
+the field variables ("f1", "f2", etc.), user variables, parameters,
+and various builtin variables. All such variables may be used equivalently
+within expressions. Only the builtin variables are writable by the
+program.
+.nh 2
+User Variables
+
+ User variables are named by the user program; only the first 8 characters
+of the variable name are significant. A user variable is created when it
+is first used in an assignment statement. If the first reference is in a
+modify and replace assignment, integer and real variables are initialized
+to 0 and string variables are initialized to the null string, before the
+modify operation takes place. It is an error if a user variable is first
+referenced in an expression.
+.nh 2
+Program Parameters
+
+ The parameter variables are optional positional arguments to the
+\fBlcalc\fR procedure. There are nine such parameters, "$1" through "$9".
+The special parameter "$nargs" specifies the number of these parameters
+set on the \fBlcalc\fR command line (the \fBlist\fR and \fBprogram\fR
+arguments to \fBlcalc\fR are not counted). Parameters are read only.
+.nh 2
+Builtin Variables
+
+ The list calculator manages a number of variables internally. These
+variables describe the list and record currently being processed, and are
+read only to the user program (with one exception). The internal variables
+are used primarily for conditional statements to be executed only at certain
+times.
+
+.ls
+.ls nfiles
+The number of files in the input list (file template).
+.le
+.ls rnum
+The record number within the list \fBfile\fR currently being processed.
+The first record is number 1.
+.le
+.ls arnum
+The absolute record number.
+.le
+.ls nfields
+The number of fields in the current record.
+.le
+.ls nchars
+The number of characters in the current record.
+.le
+.ls nlines
+The number of input lines of text in the current record.
+.le
+.ls fname
+The name of the input file currently being processed.
+.le
+.ls outfile
+The name of the output file. This parameter is writable by the program.
+If modified by the program, the current output file is closed and the
+new output file is created for writing.
+.le
+.ls atbol
+Set when processing the first record of the first file.
+.le
+.ls ateol
+Set once the last record of the last file has been processed.
+.le
+.ls atbof
+Set when processing the first record of a file.
+.le
+.ls ateof
+Set once the last record of a file has been processed, before reading
+the next file.
+.le
+.le
+
+.nh
+Examples
+
+ The list calculator is a very powerful tool and it is difficult to
+present enough examples to illustrate all of the possible applications.
+Furthermore, in many applications the list calculator is often used in
+combination with other tools such as \fBsort\fR and \fBgraph\fR; we
+will not use such programs in our examples here.
+
+.nh 2
+Simple bandpass filter
+
+Given a three column list {x,y,string}, pass only those lines for which
+y is greater than 100 and less than or equal to 140:
+
+ lcalc list, "f2 > 100 && f2 <= 140 ?"
+
+Pass only records in list1 wherein the third field has the same value
+as the fifth field of list2:
+
+ lcalc "list1,list2", "l1.f3 == l2.f5 ? r1"
+
+.nh 2
+Simple bandstop filter
+
+Pass only those records which do \fInot\fR contain the substrings
+"obj1, "obj2", or "obj3":
+
+ lcalc list, "!(@obj1 || @obj2 || @obj3) ?"
+
+.nh 2
+Rearranging and extracting fields
+
+Move fields 8 and 9 to the beginning of the list:
+
+ lcalc list, "f8,f9,f[1:7],f[10:]"
+
+Reverse the order of all fields in each record:
+
+ lcalc list, "f[-*]"
+
+Reverse the text of each record:
+
+ lcalc list, "r[-*]"
+
+Extract fields 2 and 3 from a list:
+
+ lcalc list, "f2,f3"
+
+.nh 2
+Merging lists
+
+Simple merge of two lists:
+
+ lcalc "list1,list2", "r1 r2"
+
+.nh 2
+Arithmetic operations upon lists
+
+Scale the third field of each record of a list by the factor 5e3
+(if there is a third field):
+
+ lcalc list, "f1, f2, nfields >= 3 ? f3 * 1e3, f[4:]"
+
+Print the log of the sum of the first three fields of each record:
+
+ lcalc list, "log(f1+f2+f3)"
+
+Print the sum of the second field of \fIall\fR records in the list:
+
+ lcalc list, "s+=f2; ateof ? 'sum is ' s"
+
+.nh 2
+Miscellaneous examples
+
+Execute the program in file "prog" on a list, passing two arguments:
+
+ lcalc list, "@prog", 33, "circle"
+
+Process a list according to a complex program entered via the standard input:
+
+ lcalc list, "@STDIN"
+
+Print record 55 of a list:
+
+ lcalc list, "rnum == 55 ?"
+
+Edit a list, replacing the third field in each record with the string
+"circle" if the input value of the field is "box":
+
+ lcalc list, "f1,f2, f3 == box ? circle : f3, f[4:]"
+
+.nh 2
+Possible looping examples
+
+ A concise notation for repeating the same operation on a set of fields
+would be useful. Use of a very general construct such as the \fBfor\fR
+loop is probably not justified, because such operations can already be
+performed in a CL script. For the list calculator it would be preferable
+to have a very concise notation, even if it is not as flexible. One possible
+notation is shown in the example below. The loop variable "fi" is automatically
+assigned, and represents field "i" of the record, where i takes on the values
+specified by the section. If more than a single statement is to be looped
+on, braces must be used to group statements. If loops are nested, the
+outer (leftmost) loop is assigned the loop variable fi, the next fj, and so on.
+
+Print the sum of all fields in each record:
+
+ lcalc list, "s=0; [*] s += fi; s"
+
+Reverse the characters in each field, without changing the ordering
+of the fields:
+
+ lcalc list, "[*] fi[-*]"
+.endhelp
diff --git a/pkg/lists/doc/Lintran.spc.hlp b/pkg/lists/doc/Lintran.spc.hlp
new file mode 100644
index 00000000..9dd5ff98
--- /dev/null
+++ b/pkg/lists/doc/Lintran.spc.hlp
@@ -0,0 +1,60 @@
+.help lintran Mar84 lists
+
+.nf
+List Operator LINTRAN
+
+ Performs a linear translation on each element of the input list,
+producing a transformed list as output.
+
+ lintran (list)
+
+An input line may contain a variable number of fields. Two fields of each
+input line are designated as the x and y coordinates (default cols 1,2).
+All other fields are to be preserved across the transformation. Lines which
+begin with a sharp ("#") are considered comment lines and are passed on to
+the output unmodified, as are blank lines. If either if x or y are indefinite
+and a pure translation or scale change is being performed, the corresponding
+output coordinate will be indefinite. If either input coordinate is indefinite
+and a rotation is being performed, both output coordinates will be indefinite.
+
+
+Parameters:
+
+ list
+ List or lists to be transformed (template).
+
+ xcol = 1, ycol = 2
+ Columns containing the x and y coordinates.
+
+ x1 = 0.0, y1 = 0.0
+ Current origin.
+
+ xscale = 1.0, yscale = 1.0
+ Scale factor to be applied to the input coordinates, relative
+ to the current origin [x0,y0].
+
+ angle = 0.0
+ Rotation angle about the origin [x0,y0].
+
+ x2 = 0.0, y2 = 0.0
+ New origin; applied after scaling and rotating the input coords.
+
+
+Examples:
+
+ Shift a coordinate list from the default origin [0,0] to the origin
+ [10.5,30], saving the result in the file "newlist":
+
+ lintran list, x2=10.5, y2=30, > newlist
+
+ Apply a shift of +3.4 units in x, -1.3 units in y to the input list
+ read from the standard input, writing the output list on the standard
+ output:
+
+ (list stream) | lintran x2=3.4, y=-1.3
+
+ Take x and y from columns 2 and 3, rotate 45 degrees:
+
+ lintran list, xcol=2, ycol=3, angle=45
+.fi
+.endhelp
diff --git a/pkg/lists/doc/Lists.hlp b/pkg/lists/doc/Lists.hlp
new file mode 100644
index 00000000..5b90ca7b
--- /dev/null
+++ b/pkg/lists/doc/Lists.hlp
@@ -0,0 +1,569 @@
+.help utilities May83 "IRAF System Utilities"
+.sh
+Basic IRAF System Utilities
+
+ A number of standard utilities are available as part of the IRAF
+user interface. These utilities, most of which operate on files, are
+summarized later in this document. A general discussion of files in
+the IRAF system follows. The reader is assumed to have some familiarity
+with the IRAF command language (CL).
+
+
+.sh
+Virtual File Names
+
+ File names may be specified in a machine independent fashion, or with
+OS dependent pathnames. A Virtual File Name (VFN) has the following form:
+
+
+.nf
+ ldir$root.extn
+
+where
+
+ ldir logical directory or device name
+ root root or base file name
+ extn extension denoting the type of file
+.fi
+
+
+The LDIR and EXTN fields are optional. The ROOT and EXTN fields may contain
+up to 20 characters selected from the set [a-zA-Z0-9_.+-#]. The EXTN field
+may not exceed three characters. The EXTN field is separated from the ROOT
+by the character "." (dot). If the ROOT field contains one or more occurrences
+of the dot character, the final dot delimited field is understood to be
+the extension.
+
+Logical directories are defined in the CL, using the SET command to associate
+an OS dependent pathname with a keyword in the environment table. Logical
+directory prefixes are recursively expanded.
+
+A number of standard logical directories and devices are defined by the CL
+at startup time. Additional logical directories are defined by applications
+packages upon entry, and become undefined when dictionary space is reclaimed
+on exit from the package. The user may override environment definitions at
+will, by issuing SET commands to redefine environment variables.
+
+
+.sh
+File List Templates
+
+ Whenever it makes sense, the IRAF utilities are set up to process a list
+of files, rather than a single file. In the descriptions of the standard
+utilities in the next section, "files" is a template or pattern specifying
+a list of files to be processed in some way. The template is a string type
+parameter to the CL, which is expanded by a procedure (CLGFIL) in the
+compiled systems or applications task into an EOF terminated list of files.
+
+A template may consist of one or more file names, directory names,
+list file names, or patterns. List elements are delimited by commas.
+A list file is denoted by prepending the character "@" to the pathname
+of the list file. A pattern may be applied to the contents of either
+a list file or a directory. The pattern is separated from the list file
+or directory name by the character "$". A pattern all by itself is
+applied to the current directory. Either logical or OS dependent
+pathnames may be used.
+
+A list element may refer only to a single directory. Thus, one cannot
+specify a pattern such as "*/*.x", as is possible in UNIX.
+
+Some examples of templates follow:
+
+.nf
+ file
+ "file1, file2"
+ "*.x"
+ "[A-Z]*, *.com, ../$, ../fio/$*.x, lib$*.h, file, @list$*.vs"
+ "sia1:[iraf.lib]$*.h, uparm$cl_*.par"
+.fi
+
+The magic filenames "STDIN", "STDOUT", and "STDERR" have a special
+meaning. Passing one of these special filenames to a task causes
+the named stream to be "reopened", transparently to the applications
+program. Thus, for example, one can reference "STDIN" in a template,
+and the applications program will read from the standard input when
+it opens the corresponding file in the template.
+
+For example,
+
+ cl> concat "file1, @STDIN, STDIN, file2", > ofile
+
+concatenates the file "file1", the contents of the files named in the
+standard input (until the first EOF), the contents of the standard input
+itself (until the second EOF), and the contents of the file "file2",
+placing the output in the file "ofile".
+
+
+.sh
+File Protection and Clobber
+
+ The IRAF file interface (FIO) provides file protection and synchronization
+facilities, under control of user definable environment variables.
+
+File "clobber" refers to the overwriting of an existing file when a new
+file of the same name is created as an output file. If "clobber" is
+defined as "no" in the environment, an IRAF task will abort if a new file
+would clobber an existing file. If file clobber is enabled, FIO will try
+to overwrite the old file, and will abort if it cannot do so.
+
+ cl> set clobber = "yes"
+
+More explicit file protection is provided by the CL commands PROTECT and
+UNPROTECT. A protected file cannot be deleted, accidentally or otherwise,
+until the protection has been removed with the UNPROTECT command or system
+call.
+
+A final form of file protection is provided to prevent a file from being
+clobbered which is already open by a task. Thus, "COPY file,file" will
+abort when FIO discovers that "file" is already opened for reading. This
+holds even if file clobber is enabled.
+
+
+.sh
+File Synchronization
+
+ File synchronization is useful when a process requires exclusive access
+to a file which is already open for exclusive access by another process.
+When this situation occurs, the second task may abort with a message stating
+that it cannot access the file, or the task may wait for the file to become
+available. File waiting is especially important for batch processes.
+
+ cl> set file_wait = "yes"
+
+The file wait option is controlled by the "file_wait" variable in the
+environment. If file waiting is enabled, and a process finds that it
+has to wait to access a file, a warning message will be printed on the
+standard error output before the affected process goes to sleep.
+
+
+
+.sh
+Description of the Standard Utility Routines
+
+ Most of the system utilities are set up to read from either the
+standard input or a list of files. If not reading from the standard
+input, and the input file template is not given on the command line,
+a prompt will be issued for the input file list. If the output is a
+single file or directory, and output is not redirected, a prompt will
+be issued for the output file.
+
+The following list of system utilities is expected to adequately meet
+the needs of both general users and programmers. Most notably missing
+are file editing facilities and the X-compiler. These will be added
+to the system utilities package at some point in the future. Other more
+specialized utilities and tools, such as are needed for general image
+processing, graphics, database management, magtape i/o, and so on, will
+be provided in the form of new packages in the months to come.
+
+.ks
+.ls 4 ALLOCATE device
+
+Allocate a device (e.g., a tape drive). The standard logical tape
+drive names will probably be "mt0" and "mt1".
+.le
+.ke
+
+.ks
+.ls CLEAR
+
+Clear the terminal screen.
+.le
+.ke
+
+.ks
+.ls COLUMNS [files] [, c = "1,3,5-8"]
+
+Breaks the named file or files (or the standard input) up into a stream
+of words, written one word per line on the standard output. A "word"
+is any whitespace delimited sequence of characters, or a quoted string.
+
+The hidden parameter COLUMNS may be used to extract only a particular column,
+or any list of columns, from each line. If the list contains only the
+element "0" (the default) all columns are extracted, and placed on separate
+output lines. If multiple columns are specified, only those columns given
+in the list are extracted, and all extracted columns from an input line
+appear together on a single output line. If the last element in the list
+is "0", all remaining columns in the input line are extracted and placed
+on the output line.
+
+.nf
+Hidden params:
+ columns string ["0"] List of columns.
+.fi
+.le
+.ke
+
+.ks
+.ls CONCATENATE [files] [,output_file]
+
+Concatenate the input files to the output file. If no input file is
+given, the standard input is used. If no output file is given, the
+standard output is used.
+
+.nf
+hidden params:
+ otype string ["*"] text or binary output file
+ append yes/no [no] append to output file
+.fi
+.le
+.ke
+
+.ks
+.ls COPY [file | files] [,output_file | directory]
+
+Copy the input file to the output file, or copy each file in the
+input list to the directory given as the second argument.
+
+.nf
+hidden params:
+ otype string ["*"] text or binary output file
+ append yes/no [no] append to output file
+.fi
+.le
+.ke
+
+.ks
+.ls COUNT [files]
+
+Count the number of lines, words, and characters in each file
+in the input list. Print the totals for each file and for all files.
+.le
+.ke
+
+.ks
+.ls DEALLOCATE device
+
+Deallocate a previously allocated device (e.g., a tape drive).
+.le
+.ke
+
+.ks
+.ls DELETE [files]
+
+Delete the named files. A warning message is printed if a file
+cannot be deleted. It is not considered an error to attempt to
+delete a file which does not exist. Protected files cannot be
+deleted.
+.le
+.ke
+
+.ks
+.ls DIRECTORY [files] [,op=string]
+
+Tabulate information on all files matching the template given as the
+first argument on the standard output. If no template is given, the
+contents of the current directory are displayed.
+
+.nf
+hidden params:
+ option string ["c"] 1 one-column format
+ a use time of last access
+ c n-column format
+ l long format
+ s add size in Kb
+ t time sort
+ r reverse sort
+
+e.g.: "dir op=l" (show current directory, long form)
+ "dir '*.x',op=lt" (all ".x" files in cwd, long form)
+.fi
+.le
+.ke
+
+.ks
+.ls DISKSPACE
+
+Summarize the amount of disk space available on the local system.
+This command and its output are machine dependent. This command
+may not be available on all systems.
+.le
+.ke
+
+.ks
+.ls ECHO [arglist]
+
+Echo any arguments on the standard output.
+.le
+.ke
+
+.ks
+.ls HEAD [files]
+
+Print the first few lines of each of the named files on the standard
+output. A brief header is printed to identify each file.
+
+.nf
+hidden params:
+ nlines int [8] number of lines to print
+.fi
+.le
+.ke
+
+.ks
+.ls HELP [task(s)]
+
+Retrieve documentation for the named task(s) from the help database,
+and format it on the standard output. If no task name is given, the
+tasks comprising the current package are summarized, one line per task
+(task name followed by a brief description). Help may be obtained for
+multiple tasks by supplying a template. Tasks not in the current
+package search path may be referenced by specifying the pathname to
+the task ("package.task").
+
+.nf
+Hidden params:
+ option string [h] h full help text
+ u usage section only
+ p program documentation
+ s source code
+ f give file names
+
+ file fname [""] file containing help text
+ lmargin int [1]
+ rmargin int [75]
+ page yes/no [yes] paginate output
+ nlpp int [24] number of lines per page
+.fi
+.le
+.ke
+
+.ks
+.ls LCASE [file]
+
+Copy the named file or the standard input (a text stream) to the
+standard output, converting all alphabetic characters to lower case.
+.le
+.ke
+
+.ks
+.ls MANPAGE [task(s)]
+
+Print "manual pages" for each of the named tasks. Manual pages are
+produced by breaking the help text for a task up into successive
+pages delimited by formfeed characters. Each page has a header and
+a page number. To print manual pages, the output of MANPAGE should
+be piped to PRINT ("manpage task(s) | print").
+
+.nf
+Hidden params:
+ lmargin int [1] left margin
+ rmargin int [72] right margin
+ nlpp int [60] number of lines per page
+ first_page int [1] first page to be printed
+ last_page int [0] last page to be printed
+ file fname [""] file containing help text
+.fi
+.le
+.ke
+
+.ks
+.ls MATCH pattern [,files] [,rev+]
+
+Search each file for the given pattern. Copy a line to the standard
+output if the pattern can be matched. Match against the standard input
+if no files are named.
+
+.nf
+hidden params:
+ reverse yes/no [n] print lines NOT matched
+.fi
+.le
+.ke
+
+.ks
+.ls PAGE [files]
+
+The named files (or the standard input) are displayed a page at a
+time on the standard output.
+
+.nf
+Query mode params:
+ continue y/n [y] query mode param, used to
+ provide the pause at the
+ end of each page, or to
+ exit early.
+hidden params:
+ nlpp int [24] number of lines per page
+
+.fi
+.le
+.ke
+
+.ks
+.ls PRINT [files]
+
+The named files (or the standard output) are printed on the standard
+line printer device. If a list of files are to be printed, each
+file is printed started on a new page, and file pages are broken and
+printed with numbered headers. If PRINT is reading from its standard
+input, the input stream is copied to the printer without pagination.
+
+The input stream may contain ASCII standard control characters (e.g.
+formfeed), which will be processed if necessary prior to transmission
+to the output device.
+
+.nf
+hidden params:
+ page yes/no [no] paginate the standard input
+ nlpp int [60] number of lines per page
+ szline int [132] maximum line length
+ device string name of printer device
+.fi
+.le
+.ke
+
+.ks
+.ls PROTECT [files]
+
+Protect the named files from deletion or clobber, accidental or
+otherwise. It is not considered an error to attempt to protect
+a file which is already protected. Protecting a file only prevents
+deletion of the file: write permission is not withdrawn.
+.le
+.ke
+
+.ks
+.ls RENAME [file | files] [,output_file | directory]
+
+Rename a file, or move each file in the input list to the directory
+given as the second argument.
+.le
+.ke
+
+.ks
+.ls SORT [files] [,options]
+
+Sort and merge the text files named in the list, or sort the standard
+input if no list.
+
+.nf
+hidden params:
+ numeric yes/no [n] numeric sort
+ reverse yes/no [n] reverse the sense of the sort
+ column integer [1] column to be sorted
+ whitespace yes/no [y] ignore leading whitespace
+.fi
+.le
+.ke
+
+.ks
+.ls SPY [v+]
+
+Get information on who is using the system, what they are up to, how
+much cpu time, etc., they have used, and so on. This command, and the
+information it gives, are machine dependent. This command may not be
+available on all systems.
+
+.nf
+hidden params:
+ verbose yes/no [no] get more information
+.fi
+.le
+.ke
+
+.ks
+.ls TABLE [files]
+
+The input, consisting of a list of words, one word per line, is read
+into a buffer in memory, and organized into a table which is printed
+on the standard output. The size of the table which can be formatted
+is limited by the amount of available buffer space.
+
+.nf
+Hidden params:
+ ncols int [0] desired number of columns
+ lmargin int [1] left margin of table
+ rmargin int [75] right margin of table
+ maxch int [0] max chars to print from each
+ word or string in the input.
+.fi
+.le
+.ke
+
+.ks
+.ls TAIL [files]
+
+Print the last few lines of each of the named files on the standard output.
+
+.nf
+hidden params:
+ nlines int [8] number of lines to print
+.fi
+.le
+.ke
+
+.ks
+.ls TEE [files]
+
+Copy the standard input to the standard output, as well as to each
+of the named files.
+
+.nf
+hidden params:
+ otype string ["*"] text or binary output file
+ append yes/no [n] append to the named files
+.fi
+.le
+.ke
+
+.ks
+.ls TIME
+
+Print the current time and date.
+.le
+.ke
+
+.ks
+.ls TYPE [files]
+
+Copy the named files to the standard output. A brief header is
+printed at the beginning of each file, identifying the file.
+.le
+.ke
+
+.ks
+.ls UCASE [file]
+
+Copy the named file or the standard input (a text stream) to the
+standard output, converting all alphabetic characters to upper case.
+.le
+.ke
+
+.ks
+.ls UNPROTECT [files]
+
+Remove delete protection from the named files. It is not considered
+an error to attempt to remove protection from a file which is not
+protected.
+.le
+.ke
+
+
+
+.sh
+CL Directives
+
+.ks
+.ls CHDIR directory
+
+Change the current working directory. CHDIR without any arguments
+prints the name of the current working directory on the standard
+output.
+.le
+.ke
+
+.ks
+.ls SET [param [= value_string]]
+
+Set the value of an environment variable. If the variable is not
+already defined, it becomes defined. If the variable is already
+defined, the old value is (temporarily and silently) overridden.
+A variable defined or redefined with SET is discarded when CL
+dictionary space is reclaimed.
+
+SET without any arguments displays the current environment.
+.le
+.ke
+
+(etc.)
+.endhelp
diff --git a/pkg/lists/doc/average.hlp b/pkg/lists/doc/average.hlp
new file mode 100644
index 00000000..3cfd5599
--- /dev/null
+++ b/pkg/lists/doc/average.hlp
@@ -0,0 +1,49 @@
+.help average Jul86 lists
+.ih
+NAME
+average -- compute the average and standard deviation
+.ih
+USAGE
+average option
+.ih
+PARAMETERS
+.ls option
+Chosen from "add", "subtract" or "new_sample",
+in which case the numbers averaged are those in STDIN.
+If no argument is given on the command line, "new_sample" is assumed.
+.le
+.ih
+DESCRIPTION
+Task \fIaverage\fR computes the average and standard deviation of a list
+of numbers. Numeric input is read from STDIN with one number per line.
+The mean, sigma and number of samples are written to the standard
+output.
+
+By default, the sample is taken to be
+the set of numbers in the standard input when \fIaverage\fR is run.
+Additional points can be added to or deleted from the sample by rerunning
+\fIaverage\fR with \fBoption\fR equal to one of the following:
+.nf
+
+ add -- add points to the sample, recalculate mean and sigma
+ sub -- subtract points from the sample
+.fi
+
+The sample is reinitialized by setting \fBoption\fR = "new_sample".
+.ih
+EXAMPLES
+Run \fIaverage\fR on the list of numbers in file "numbers".
+.nf
+
+ cl> type numbers | average
+.fi
+
+Add in to the sample the list of numbers in file "numbers.2".
+.nf
+
+ cl> average add < numbers.2
+.fi
+.ih
+SEE ALSO
+lintran
+.endhelp
diff --git a/pkg/lists/doc/columns.hlp b/pkg/lists/doc/columns.hlp
new file mode 100644
index 00000000..a4f304fa
--- /dev/null
+++ b/pkg/lists/doc/columns.hlp
@@ -0,0 +1,38 @@
+.help columns Nov88 lists
+.ih
+NAME
+columns -- break a multicolumn list into multiple single column lists
+.ih
+USAGE
+columns filename numcols
+.ih
+PARAMETERS
+.ls filename
+Name of the input table file.
+.le
+.ls numcols
+The number of columns in the input file.
+.le
+.ls outroot = "col."
+Root name of the output column files.
+.le
+.ih
+DESCRIPTION
+Task \fIcolumns\fR is used to reformat a multicolumn list file into separate
+files, such that one output file is created for each column in the input
+file. It is used to break multicolumn tables into simple CL lists.
+Comment lines beginning with the character "#" are ignored. All data
+is transferred as text. One file \fBoutroot\fRn is produced for each
+column in the input table.
+.ih
+EXAMPLES
+Make 3 files named datacol.1, datacol.2 and datacol.3 from the 3 column
+table dtable:
+.nf
+
+ cl> columns dtable 3 outroot=datacol.
+.fi
+.ih
+SEE ALSO
+fields
+.endhelp
diff --git a/pkg/lists/doc/lintran.hlp b/pkg/lists/doc/lintran.hlp
new file mode 100644
index 00000000..94133e34
--- /dev/null
+++ b/pkg/lists/doc/lintran.hlp
@@ -0,0 +1,103 @@
+.help lintran Apr84 lists
+.ih
+NAME
+lintran -- perform a linear transformation of a list
+.ih
+USAGE
+lintran files
+.ih
+PARAMETERS
+.ls files
+List file or files to be transformed.
+.le
+.ls xfield = 1, yfield = 2
+Fields containing the x and y coordinates.
+.le
+.ls x1 = 0.0, y1 = 0.0
+Coordinates of current origin.
+.le
+.ls xscale = 1.0, yscale = 1.0
+Scale factor to be applied to the input coordinates, relative
+to the current origin [x1,y1].
+.le
+.ls angle = 0.0
+Rotation angle about the origin [x1,y1]. This angle, measured
+counter clockwise from the positive x axis, is entered in
+degrees, unless \fBradians\fR = yes.
+.le
+.ls x2 = 0.0, y2 = 0.0
+Coordinates of the new origin; input coordinates are shifted by an
+amount (x2-x1) and (y2-y1). Positive shifts indicate increasing distance
+from the current origin. Applied after scaling and rotating the input
+coordinates.
+.le
+.ls radians = no
+If this parameter is set to yes, \fBangle\fR is input
+in radians, not degrees.
+.le
+.ls min_sigdigits = 1
+The number of significant digits to be output in the transformed fields
+is the maximum of this parameter and the number of input significant digits.
+.le
+.ih
+DESCRIPTION
+Specified fields from the input list can be scaled, rotated and shifted.
+Two fields of each input line are designated
+as the x and y coordinates to be transformed (default: fields 1, 2).
+All other fields are be preserved across the transformation.
+For clarification, the equations used in the transformation are shown below:
+
+.ks
+.nf
+ 1. Subtract off the current origin:
+
+ xt = x - x1
+ yt = y - y1
+
+ 2. Scale and rotate the coordinates:
+
+ xs = xt * xscale
+ ys = yt * yscale
+ xt = xs * cos(angle) - ys * sin(angle)
+ yt = xs * sin(angle) + ys * cos(angle)
+
+ 3. Shift to the new origin:
+
+ xt = xt + x2
+ yt = yt + y2
+.fi
+.ke
+
+Comment lines and blank lines are passed on to the output unmodified
+(a comment line is any line beginning with the character '#').
+If either x or y is indefinite
+and no rotation is being performed, the corresponding
+output coordinate will be indefinite. If either input coordinate is indefinite
+and a rotation is being performed, both output coordinates will be indefinite.
+.ih
+EXAMPLES
+1. Shift the coordinate list frame1 so it represents positions
+in a second exposure of a star field, not registered with the first. Take
+the coordinates of a star in frame1 to be the current origin
+(e.g., [35.7, 389.2]); the new origin is then the coordinates of the same
+star in the second exposure ([36.9, 400.0]). The shifted list is saved in
+file "frame2":
+
+ cl> lintran frame1 x1=35.7 y1=389.2 x2=36.9 y2=400.0 > frame2
+
+2. Apply a shift of +3.4 units in x, -1.3 units in y to the input list
+read from the standard input, writing the output list on the standard
+output.
+
+ cl> list_stream | lintran x2=3.4 y2=-1.3
+
+3. Rotate a coordinate list of a 800x800 frame by 90 degrees. The
+rotated coordinate list would represent positions in the field if it had
+been rotated, for example, from East to the right to East to the top.
+Note that the rotation takes place about the central pixel [400.50,400.50]
+and that the current and new origins are the same:
+
+ cl> lintran picture x1=400.5 y1=400.5 x2=400.5 y2=400.5 angle=90
+.ih
+SEE ALSO
+.endhelp
diff --git a/pkg/lists/doc/raverage.hlp b/pkg/lists/doc/raverage.hlp
new file mode 100644
index 00000000..4d36851f
--- /dev/null
+++ b/pkg/lists/doc/raverage.hlp
@@ -0,0 +1,110 @@
+.help raverage May07 lists
+.ih
+NAME
+raverage -- running average, standard deviation, and envelope
+.ih
+USAGE
+raverage input nwin
+.ih
+PARAMETERS
+.ls input
+Input one or two column list of numbers. Any line that can't be read
+as one or two numbers is ignored which means comments are allowed. The
+special name "STDIN" may be used to read the numbers from the standard
+input pipe or redirection.
+.le
+.ls nwin
+The number of values in the running average window.
+.le
+.ls sort = no
+Numerically sort the first column of the input list by increasing value?
+This is done in an temporary file and the
+actual input file is not modified.
+.le
+.ls nsig = 0
+The number of standard deviations below and above the average for the
+envelope columns. If the value is greater than zero two extra columns
+are output formed by subtracting and adding this number of standard
+deviations to the average value. If the value is zero then the
+columns not be written.
+.le
+.ls fd1, fd2
+Internal parameters.
+.le
+.ih
+DESCRIPTION
+This task computes the running average and standard deviation of a
+one or two column list. For a one column list the ordinal value is
+added. Note that the ordinal is only for the lines that are successfully
+read so any comments are not counted. So the internal list is always
+two columns.
+
+The input may be a physical file or the standard input. The standard
+input is specified by the special name "STDIN". All the input values
+are read and stored in a temporary file prior to computing the output.
+A temporary file is also used if the input is to be numerically sorted
+by increasing value of the first column. Note that the sorting is done
+before adding the implied ordinal for one column lists.
+
+The output has four or six columns depending on whether \fInsig\fR is
+zero or greater than zero.
+
+.nf
+ average1 average1 stddev number [lower upper]
+
+ average1 - the running average of the first column
+ average2 - the running average of the second column
+ stddev - standard deviation of the second column
+ number - number of values in the statistic
+ lower - optional lower envelope value
+ upper - optional upper envelope value
+.fi
+
+The "number" of values may be less than the window if the window size is
+larger than the list.
+
+The number of lines will generally be less than the input because there is
+no boundary extension. In other words the first output value is computed
+after the first \fInwin\fR values have been read and the last output value
+is computed when the end of the list is reached.
+
+The envelope columns are computed when \fInsig\fR is greater than zero.
+The values are
+
+.nf
+ lower = average2 - nsig * stddev
+ upper = average2 + nsig * stddev
+.fi
+
+In many cases the data is intended to represent a scatter plot and one
+wants to show the trend and envelope as a function of the first column.
+This is where the sorting and envelope options are useful.
+.ih
+EXAMPLES
+1. Compute the running average with a window of 100 values on the list of
+numbers in file "numbers".
+.nf
+
+ cl> raverage numbers 100
+.fi
+
+2. Do this using the standard input. In this example use random numbers.
+
+.nf
+ cl> urand 100 1 | raverage STDIN 90
+.fi
+
+3. Make a scatter plot of a two column list with the trend and envelope
+overplotted.
+
+.nf
+ cl> fields numbers 1,3 | graph point+
+ cl> fields numbers 1,3 | raverage STDIN 100 sort+ nsig=3 > tmp
+ cl> fields tmp 1,2 | graph append+
+ cl> fields tmp 1,5 | graph append+
+ cl> fields tmp 1,6 | graph append+
+.fi
+.ih
+SEE ALSO
+average, boxcar
+.endhelp
diff --git a/pkg/lists/doc/rgcursor.hlp b/pkg/lists/doc/rgcursor.hlp
new file mode 100644
index 00000000..7a64ec81
--- /dev/null
+++ b/pkg/lists/doc/rgcursor.hlp
@@ -0,0 +1,94 @@
+.help rgcursor Dec87 lists
+.ih
+NAME
+rgcursor -- read the graphics cursor (makes a list)
+.ih
+USAGE
+gcursor
+.ih
+DESCRIPTION
+Task \fIrgcursor\fR iteratively reads the graphics cursor, writing the
+cursor values to the standard output. The standard output is normally
+redirected into a text file to generate a coordinate list to be used as
+input to one or more other programs. Any IRAF program which reads the
+graphics cursor may be run taking input from a list prepared in advance
+with \fIrgcursor\fR (as well as interactively, of course).
+
+A plot should be drawn on the graphics terminal before running \fIrgcursor\fR.
+When the program is run a loop is entered, reading the global graphics
+cursor until the end of file character (e.g., <ctrl/z>, <ctrl/d>) is typed.
+Each cursor read causes a line to be printed on the standard output, after
+which the cursor is again read.
+
+While the program is waiting for the cursor to be read, i.e., whenever
+the cursor crosshairs are displayed, the terminal is said to be in
+"cursor mode". While in cursor mode, various commands may be entered,
+e.g., to zoom in a feature to get a more accurate cursor position, without
+terminating the current cursor read. To read the cursor position, enter
+any key not recognized as a cursor mode command, i.e., any lower case or
+non-alphanumeric character. The actual character one should type depends
+upon the program for which the list is intended. If the program will use
+only the X and Y coordinates of the cursor any character may be typed,
+e.g., tap the space bar. If the program uses the key to determine what
+action to take, then you must type a specific key.
+
+The X and Y coordinates of the cursor position and other information
+comprising the cursor value are printed on the standard output when the
+cursor is read. The cursor position may optionally be marked whenever the
+cursor is read, by setting the ":.markcur" option when in cursor mode.
+This is useful when preparing long lists to keep track of the objects
+or features that have already been marked.
+
+For additional information on \fIcursor mode\fR and the format of a cursor
+value string, type "help cursor". For information on the key and string values
+required by the applications program for which the cursor list is intended,
+consult the documentation for that program.
+.ih
+EXAMPLES
+1. Interactively generate a starlist (file "starlist") to be used as input
+to another program, e.g., for digital photometry. In this case one would
+probably want to start with a contour plot labeled in image pixel coordinates.
+
+.nf
+ cl> contour m74 # make the plot
+ cl> rgcursor > starlist # make the object list
+
+ At this point, the cursor loop is entered and the terminal
+ is placed into cursor mode. Any of the following commands
+ might be appropriate:
+
+ \fBcommand\fR \fBaction\fR
+
+ :.markcur+ enables marking of the cursor position
+ when the cursor is read
+
+ :radius 7 set object radius in pixels
+ :annulus 10 15 set annulus radii to be used for sky
+ space_bar mark the position of an object
+ space_bar mark the position of an object
+ (etc.)
+
+ Z zoom in on a feature to get a more
+ accurate cursor read
+ space_bar mark the position of the object
+ space_bar mark the position of another object
+ 0 replot the original plot
+
+ <crtl/z> (EOF) terminates rgcursor
+.fi
+
+Given the above command sequence, the output file "starlist" might
+contain the following cursor values.
+
+.nf
+ 234.435 78.9292 1 : radius 7
+ 234.475 78.9243 1 : annulus 10 15
+ 67.2822 282.319 1 \40
+ 766.252 344.224 1 \40
+ 822.918 311.748 1 \40
+ 76.8272 822.139 1 \40
+.fi
+.ih
+SEE ALSO
+rimcursor, cursor
+.endhelp
diff --git a/pkg/lists/doc/rimcursor.hlp b/pkg/lists/doc/rimcursor.hlp
new file mode 100644
index 00000000..9287579a
--- /dev/null
+++ b/pkg/lists/doc/rimcursor.hlp
@@ -0,0 +1,270 @@
+.help rimcursor Mar92 lists
+.ih
+NAME
+rimcursor -- repeatedly read and return image cursor values
+.ih
+USAGE
+rimcursor [image]
+.ih
+PARAMETERS
+.ls image
+The name of the reference image to which coordinates should refer.
+This parameter will be queried only if \fBrimcursor\fR cannot obtain
+the reference image name by other means; e.g. when cursor reads are
+being performed using the image display, \fBrimcursor\fR will assume that
+\fIimage\fR is the currently displayed image.
+.le
+.ls wcs = "logical"
+The world coordinate system (\fIwcs\fR) to be used for coordinate output.
+The following standard world systems are predefined.
+.ls logical
+Logical coordinates are image pixel coordinates relative to the image currently
+being displayed. This is what the raw cursor read returns, so by default,
+\fBrimcursor\fR merely passes back the raw image cursor coordinates as
+would be returned by "=imcur".
+.le
+.ls physical
+The physical coordinate system is invariant with respect to linear
+transformations of the physical image matrix. For example, if the reference
+image was created by extracting a section of another image, the physical
+coordinates of an object in the reference image will be the pixel coordinates
+of the same object in the original image. The physical coordinate system
+thus provides a consistent coordinate system (a given object always has the
+same coordinates) for all images, regardless of whether any user world
+coordinate systems have been defined.
+.le
+.ls world
+The "world" coordinate system is the \fIcurrent default WCS\fR.
+The default world system is the system named by the environment variable
+\fIdefwcs\fR if defined in the user environment and present in the reference
+image WCS description, else it is the first user WCS defined for the image
+(if any), else physical coordinates are returned.
+.le
+
+In addition to these three reserved WCS names, the name of any user WCS
+defined for the reference image may be given. A user world coordinate system
+may be any linear or nonlinear world system.
+.le
+.ls wxformat = "", wyformat = ""
+The default output format for the x and y coordinates. If wxformat or wyformat
+are undefined, rimcursor uses formatting options stored with the WCS in the
+image header. If the WCS formatting options are not defined in the image
+header, then rimcursor uses a default format.
+.le
+.ls cursor = ""
+The source for image cursor input. By default, the hardware image cursor
+is read.
+.le
+.ih
+DESCRIPTION
+The task \fBrimcursor\fR iteratively reads the image display cursor,
+writing the cursor values to the standard output. The standard output
+may be redirected into a text file to generate a coordinate list for use
+as input to other tasks. Any IRAF program which normally reads the image
+cursor interactively may be run taking input from a list prepared
+using \fBrimcursor\fR.
+
+An image should be displayed on the image display device before running
+\fBrimcursor\fR, and the device set to display the desired frame.
+When the program is run, a loop is entered reading the image
+cursor until the end of file character (e.g., <ctrl/d> or <ctrl/z>) is typed.
+Each cursor read causes a line to be printed on the standard output, after
+which the cursor is again read. Cursor values consist of two coordinates,
+a coordinate system identification (currently identifying the display
+frame), and the key or colon command typed to terminate the cursor read.
+Note this task does not return pixel value information, see \fBimexamine\fR
+for this purpose.
+
+While the program is waiting for the cursor to be read, i.e. whenever
+the image cursor is blinking rapidly, the terminal is said to be in
+"cursor mode". To read the cursor position, enter any key not
+recognized as a cursor mode command (currently there are no cursor mode
+commands for the image cursor so any character may be typed).
+The colon key returns to text
+input for a line of text terminated by a carriage return. This is
+called a "colon command". The actual character or colon command one
+types depends upon the program for which the list is intended. If the
+program will use only the coordinates of the cursor any character may be
+typed, e.g., the space bar. If the program uses the key value to
+determine what action to take, then you must type a specific key.
+
+The X and Y coordinates of the cursor position and other information
+comprising the cursor value are printed on the standard output when the
+cursor is read. To keep track of objects or features marked in a long
+set of cursor reads one may want to enable display marking if provided
+by the display device; e.g. the \fBimtool\fR display server.
+Other useful features, such as zoom, may be available in the display
+device also.
+
+The coordinates returned by \fBrimcursor\fR depend on the type of
+world coordinate system chosen by parameter \fIwcs\fR and those defined
+by the reference image. The default "logical" coordinates are the
+image pixel coordinates being displayed. This is available for all
+images and may be required by other tasks which read the generated list.
+The "physical" coordinate system provides coordinates from the "original
+data image" irrespective of any linear transformations (such as image
+sections) used to generate the current image from the original data image.
+Coordinates in a user or application defined linear or nonlinear world
+coordinate system may be obtained by setting the \fIwcs\fR parameter to
+"world" for coordinate output in the default world system, or to the name
+of the specific world system for which coordinates are desired.
+An example of a world coordinate system for direct astronomical images
+is RA and DEC using the tangent (gnonomic) projection.
+
+Coordinate transformations from the logical coordinates of image pixels
+as given by a raw image cursor read, to physical or world coordinates is
+performed by \fBrimcursor\fR. This aspect of the task may be used
+to transform image pixel coordinate lists of x and y values, as produced
+by some tasks such as \fBapphot\fR or \fBdaophot\fR into world
+coordinates by specifying cursor input from the file rather than the
+image display cursor.
+
+.ih
+FORMATS
+A format specification has the form "%w.dCn", where w is the field
+width, d is the number of decimal places or the number of digits of
+precision, C is the format code, and n is radix character for
+format code "r" only. The w and d fields are optional. The format
+codes C are as follows:
+
+.nf
+b boolean (YES or NO)
+c single character (c or '\c' or '\0nnn')
+d decimal integer
+e exponential format (D specifies the precision)
+f fixed format (D specifies the number of decimal places)
+g general format (D specifies the precision)
+h hms format (hh:mm:ss.ss, D = no. decimal places)
+m minutes, seconds (or hours, minutes) (mm:ss.ss)
+o octal integer
+rN convert integer in any radix N
+s string (D field specifies max chars to print)
+t advance To column given as field W
+u unsigned decimal integer
+w output the number of spaces given by field W
+x hexadecimal integer
+z complex format (r,r) (D = precision)
+
+
+Conventions for w (field width) specification:
+
+ W = n right justify in field of N characters, blank fill
+ -n left justify in field of N characters, blank fill
+ 0n zero fill at left (only if right justified)
+absent, 0 use as much space as needed (D field sets precision)
+
+
+Escape sequences (e.g. "\n" for newline):
+
+\b backspace (not implemented)
+\f formfeed
+\n newline (crlf)
+\r carriage return
+\t tab
+\" string delimiter character
+\' character constant delimiter character
+\\ backslash character
+\nnn octal value of character
+
+Examples
+
+%s format a string using as much space as required
+%-10s left justify a string in a field of 10 characters
+%-10.10s left justify and truncate a string in a field of 10 characters
+%10s right justify a string in a field of 10 characters
+%10.10s right justify and truncate a string in a field of 10 characters
+
+%7.3f print a real number right justified in floating point format
+%-7.3f same as above but left justified
+%15.7e print a real number right justified in exponential format
+%-15.7e same as above but left justified
+%12.5g print a real number right justified in general format
+%-12.5g same as above but left justified
+
+%h format as nn:nn:nn.n
+%15h right justify nn:nn:nn.n in field of 15 characters
+%-15h left justify nn:nn:nn.n in a field of 15 characters
+%12.2h right justify nn:nn:nn.nn
+%-12.2h left justify nn:nn:nn.nn
+
+%H / by 15 and format as nn:nn:nn.n
+%15H / by 15 and right justify nn:nn:nn.n in field of 15 characters
+%-15H / by 15 and left justify nn:nn:nn.n in field of 15 characters
+%12.2H / by 15 and right justify nn:nn:nn.nn
+%-12.2H / by 15 and left justify nn:nn:nn.nn
+
+\n insert a newline
+.fi
+
+.ih
+EXAMPLES
+1. Interactively generate a starlist (file "starlist") to be used as input
+to another program, e.g., for digital photometry.
+
+.nf
+ cl> display dev$pix 1 # display image in frame 1
+ cl> rimcursor > starlist # make the object list
+
+ At this point, the cursor loop is entered and the terminal
+ is placed into cursor mode. The positions are marked using
+ the space bar.
+
+ space_bar mark the position of the object
+ space_bar mark the position of another object
+
+ <ctrl/z> (EOF) terminates rimcursor
+.fi
+
+Given the above command sequence, the output file "starlist" might
+contain the following cursor values.
+
+.nf
+ 441. 410. 101 \040
+ 208. 506. 101 \040
+ 378. 68. 101 \040
+.fi
+
+2. Get world coordinates for the default world coordinate system.
+
+.nf
+ cl> rimcur wcs=world
+ 12.13436 63.5565 101 \040
+ 12.13448 63.5529 101 \040
+ 12.13499 63.5588 101 \040
+.fi
+
+Since there is no format information in the image header, the coordinates are
+decimal RA and DEC in degrees.
+
+3. Output the RA and DEC coordinates for an image in sexagesimal degrees.
+
+.nf
+ cl> rimcur wcs=world xformat=%12.2h yformat=%12.2h
+ 19:47:12.25 33:15:03.66
+ 19:43:12.10 33:14:38.06
+ 19:45:12.40 33:15:56.03
+.fi
+
+4. Output the RA in sexagesimal hours and DEC in sexagesimal degrees for an
+image.
+
+.nf
+ cl> rimcur wcs=world xformat=%12.2H yformat=%12.2h
+ 13:47:12.25 47:15:03.66
+ 13:47:12.10 47:15:38.06
+ 13:47:12.40 47:15:56.03
+.fi
+
+5. Convert a list of pixel coordinates to world coordinates.
+
+.nf
+ cl> rimcur obs001 wcs=world cursor=coordlist >worldlist
+.fi
+.ih
+NOTES
+Future plans call for implementation of cursor mode commands for image
+display cursors similar to those available for graphics cursors.
+.ih
+SEE ALSO
+rgcursor, cursors
+.endhelp
diff --git a/pkg/lists/doc/table.hlp b/pkg/lists/doc/table.hlp
new file mode 100644
index 00000000..54cc0e0a
--- /dev/null
+++ b/pkg/lists/doc/table.hlp
@@ -0,0 +1,43 @@
+.help table Jan86 lists
+.ih
+NAME
+table -- format single column input into a table
+.ih
+USAGE
+table input_files
+.ih
+PARAMETERS
+.ls input_files
+List of files to be formatted, may be STDIN.
+.le
+.ls first_col = 7
+Offset to first column of table
+.le
+.ls last_col = 0
+Offset to last column of table. The value \fBlast_col\fR = 0 indicates
+right margin.
+.le
+.ls ncols = 0
+Number of columns. The value \fBncols\fR = 0 indicates maximum that will fit.
+.le
+.ls maxstrlen = 0
+Maximum string length for table entry. The value \fBmaxstrlen\fR = 0
+indicates no limit.
+.le
+.ih
+DESCRIPTION
+Task \fBtable\fR reads a list of strings from the standard input or a
+list of files and assembles a nicely formatted table. If reading
+from multiple input files, make a separate table for each. There is no
+fixed limit to the size of the table which can be formatted. The table
+is not sorted; this should be done as a separate operation if desired.
+.ih
+EXAMPLES
+1. Format a file containing names into a two column table. The table is
+sorted alphabetically first.
+
+ cl> sort names | table ncols=2
+.ih
+SEE ALSO
+words, tokens
+.endhelp
diff --git a/pkg/lists/doc/tokens.hlp b/pkg/lists/doc/tokens.hlp
new file mode 100644
index 00000000..5be408fd
--- /dev/null
+++ b/pkg/lists/doc/tokens.hlp
@@ -0,0 +1,55 @@
+.help tokens Jan86 lists
+.ih
+NAME
+tokens -- break input into stream of tokens
+.ih
+USAGE
+tokens files
+.ih
+PARAMETERS
+.ls files
+The list of files to be converted into a stream of tokens.
+.le
+.ls ignore_comments = yes
+Ignore comments in the input string?
+.le
+.ls begin_comment = "#"
+The string marking the start of a comment
+.le
+.ls end_comment = "eol"
+The string marking the end of a comment. The value \fBend_comment\fR = "eol"
+means the end of a line terminates a comment.
+.le
+.ls newlines = yes
+Is newline a legal token?
+.le
+.ih
+DESCRIPTION
+Task \fItokens\fR breaks the input up into a series of tokens.
+The makeup of the
+various tokens is defined by the FMTIO primitive ctotok, which is not very
+sophisticated, and does not claim to recognize the tokens for any particular
+language (though it does reasonably well for most modern languages). Comments
+can be deleted if desired, and newlines may be passed on to the output as
+tokens.
+
+Comments are delimited by user specified strings. Only strings which are also
+recognized by ctotok() as legal tokens may be used as comment delimiters.
+If newline marks the end of a comment, the end_comment string should be given
+as "eol". Examples of acceptable comment conventions are ("#", eol),
+("/*", "*/"), ("{", "}"), and ("!", eol). Fortran style comments ("^{c}",eol)
+can be stripped by filtering with match beforehand.
+
+Each token is passed to the output on a separate line. Multiple newline
+tokens are compressed to a single token (a blank line). If newline is not
+desired as an output token, it is considered whitespace and serves only to
+delimit tokens.
+.ih
+EXAMPLES
+Break up the source file for this task into tokens:
+
+ cl> tokens tokens.x
+.ih
+SEE ALSO
+words
+.endhelp
diff --git a/pkg/lists/doc/unique.hlp b/pkg/lists/doc/unique.hlp
new file mode 100644
index 00000000..d55d5ac0
--- /dev/null
+++ b/pkg/lists/doc/unique.hlp
@@ -0,0 +1,27 @@
+.help unique Jan86 lists
+.ih
+NAME
+unique -- remove repeated adjacent lines from a file
+.ih
+USAGE
+unique files
+.ih
+PARAMETERS
+.ls files
+List of files to be processed.
+.le
+.ih
+DESCRIPTION
+Task \fBunique\fR reads the input comparing adjacent lines. The second and
+successive copies of a line are removed; the remainder is passed on to the
+standard output.
+.ih
+EXAMPLES
+Remove repeated names from a list. Note the input file has been sorted
+alphabetically so repeated names are adjacent.
+
+ cl> sort names | unique > names.final
+.ih
+SEE ALSO
+sort
+.endhelp
diff --git a/pkg/lists/doc/words.hlp b/pkg/lists/doc/words.hlp
new file mode 100644
index 00000000..0df846a1
--- /dev/null
+++ b/pkg/lists/doc/words.hlp
@@ -0,0 +1,22 @@
+.help words Jan86 lists
+.ih
+NAME
+words -- break the input into a series of words
+.ih
+USAGE
+words files
+.ih
+PARAMETERS
+.ls files
+List of files to be processed.
+.le
+.ih
+DESCRIPTION
+Task \fBwords\fR is used to break the input up into a series of words
+or strings. A word is a sequence of characters delimited by whitespace
+or newline. A string is delimited by single or double quotes, and may not
+span more than a single line.
+.ih
+SEE ALSO
+tokens, table
+.endhelp
diff --git a/pkg/lists/filter.cl b/pkg/lists/filter.cl
new file mode 100644
index 00000000..60a0b0a6
--- /dev/null
+++ b/pkg/lists/filter.cl
@@ -0,0 +1,6 @@
+#{ Template for a list filter.
+
+{
+ while (scan (x, y) != EOF)
+ print (x, sin (y * $1))
+}
diff --git a/pkg/lists/lintran.par b/pkg/lists/lintran.par
new file mode 100644
index 00000000..f153ea04
--- /dev/null
+++ b/pkg/lists/lintran.par
@@ -0,0 +1,12 @@
+files,s,a,,,,
+xfield,i,h,1,1,100,field containing x coordinate
+yfield,i,h,2,1,100,field containing y coordinate
+min_sigdigits,i,h,3,,,minimum significant digits to be output
+x1,r,h,0.0,,,current x origin
+y1,r,h,0.0,,,current y origin
+xscale,r,h,1.0,,,scale factor relative to current origin
+yscale,r,h,1.0,,,scale factor relative to current origin
+angle,r,h,0.0,,,rotation angle
+x2,r,h,0.0,,,new x origin
+y2,r,h,0.0,,,new y origin
+radians,b,h,no,,,angle in radians?
diff --git a/pkg/lists/lintran.x b/pkg/lists/lintran.x
new file mode 100644
index 00000000..70bb59d4
--- /dev/null
+++ b/pkg/lists/lintran.x
@@ -0,0 +1,370 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <pattern.h>
+include <ctype.h>
+
+define MAX_FIELDS 100 # Maximum number of fields in list
+define TABSIZE 8 # Spacing of tab stops
+define LEN_TR 18 # Length of structure TR
+
+# The TR transformation descriptor structure.
+
+define X1 Memd[P2D($1)] # Input origin
+define Y1 Memd[P2D($1+2)]
+define XSCALE Memd[P2D($1+4)] # Scale factors
+define YSCALE Memd[P2D($1+6)]
+define THETA Memd[P2D($1+8)] # Rotation angle
+define X2 Memd[P2D($1+10)] # Output origin
+define Y2 Memd[P2D($1+12)]
+define COS_THETA Memd[P2D($1+14)]
+define SIN_THETA Memd[P2D($1+16)]
+
+
+# LINTRAN -- Performs a linear translation on each element of the
+# input list, producing a transformed list as output.
+
+procedure t_lintran()
+
+char in_fname[SZ_FNAME]
+int list
+pointer sp, tr
+int xfield, yfield, min_sigdigits
+
+int clgeti(), clpopni(), clgfil()
+
+begin
+ # Allocate memory for transformation parameters structure
+ call smark (sp)
+ call salloc (tr, LEN_TR, TY_STRUCT)
+
+ # Call procedure to get parameters and fill structure
+ call lt_initialize_transform (tr)
+
+ # Get field numbers from cl
+ xfield = clgeti ("xfield")
+ yfield = clgeti ("yfield")
+ min_sigdigits = clgeti("min_sigdigits")
+
+ # Open template of input files
+ list = clpopni ("files")
+
+ # While input list is not depleted, open file and transform list
+ while (clgfil (list, in_fname, SZ_FNAME) != EOF)
+ call lt_transform_file (in_fname, xfield, yfield, min_sigdigits, tr)
+
+ # Close template
+ call clpcls (list)
+ call sfree (sp)
+end
+
+
+# LT_INITIALIZE_TRANSFORM -- gets parameter values relevant to the
+# transformation from the cl. List entries will be transformed
+# in procedure lt_transform. Scaling is performed
+# first, followed by translation and then rotation.
+
+procedure lt_initialize_transform (tr)
+
+pointer tr
+
+bool clgetb()
+double clgetd()
+
+begin
+ # Get parameters from cl
+ X1(tr) = clgetd ("x1") # (x1,y1) = crnt origin
+ Y1(tr) = clgetd ("y1")
+ XSCALE(tr) = clgetd ("xscale")
+ YSCALE(tr) = clgetd ("yscale")
+ THETA(tr) = clgetd ("angle")
+ if (! clgetb ("radians"))
+ THETA(tr) = THETA(tr) / 57.29577951
+ X2(tr) = clgetd ("x2") # (x2,y2) = new origin
+ Y2(tr) = clgetd ("y2")
+
+ # The following terms are constant for a given transformation.
+ # They are calculated once and saved in the structure.
+
+ COS_THETA(tr) = cos (THETA(tr))
+ SIN_THETA(tr) = sin (THETA(tr))
+end
+
+
+# LT_TRANSFORM_FILE -- This procedure is called once for each file
+# in the input list. For each line in the input file that isn't
+# blank or comment, the line is transformed. Blank and comment
+# lines are output unaltered.
+
+procedure lt_transform_file (in_fname, xfield, yfield, min_sigdigits, tr)
+
+char in_fname[ARB]
+int xfield, yfield
+pointer tr
+
+char outbuf[SZ_LINE]
+int nfields, nchars, max_fields, in, nline
+int nsdig_x, nsdig_y, offset, min_sigdigits
+pointer sp, field_pos, linebuf, inbuf, ip
+double x, y, xt, yt
+int getline(), lt_get_num(), open()
+
+begin
+ call smark (sp)
+ call salloc (inbuf, SZ_LINE, TY_CHAR)
+ call salloc (linebuf, SZ_LINE, TY_CHAR)
+ call salloc (field_pos, MAX_FIELDS, TY_INT)
+
+ max_fields = MAX_FIELDS
+
+ # Open input file
+ in = open (in_fname, READ_ONLY, TEXT_FILE)
+
+ for (nline=1; getline (in, Memc[inbuf]) != EOF; nline = nline + 1) {
+ for (ip=inbuf; IS_WHITE(Memc[ip]); ip=ip+1)
+ ;
+ if (Memc[ip] == '#') {
+ # Pass comment lines on to the output unchanged.
+ call putline (STDOUT, Memc[inbuf])
+ next
+ } else if (Memc[ip] == '\n' || Memc[ip] == EOS) {
+ # Blank lines too.
+ call putline (STDOUT, Memc[inbuf])
+ next
+ }
+
+ # Expand tabs into blanks, determine field offsets.
+ call strdetab (Memc[inbuf], Memc[linebuf], SZ_LINE, TABSIZE)
+ call lt_find_fields (Memc[linebuf], Memi[field_pos],
+ max_fields, nfields)
+
+ if (xfield > nfields || yfield > nfields) {
+ call eprintf ("Not enough fields in file '%s', line %d\n")
+ call pargstr (in_fname)
+ call pargi (nline)
+ call putline (STDOUT, Memc[linebuf])
+ next
+ }
+
+ offset = Memi[field_pos + xfield-1]
+ nchars = lt_get_num (Memc[linebuf+offset-1], x, nsdig_x)
+ if (nchars == 0) {
+ call eprintf ("Bad x value in file '%s' at line %d:\n")
+ call pargstr (in_fname)
+ call pargi (nline)
+ call putline (STDOUT, Memc[linebuf])
+ next
+ }
+
+ offset = Memi[field_pos + yfield-1]
+ nchars = lt_get_num (Memc[linebuf+offset-1], y, nsdig_y)
+ if (nchars == 0) {
+ call eprintf ("Bad y value in file '%s' at line %d:\n")
+ call pargstr (in_fname)
+ call pargi (nline)
+ call putline (STDOUT, Memc[linebuf])
+ next
+ }
+
+ call lt_transform (x, y, xt, yt, tr)
+
+ call lt_pack_line (Memc[linebuf], outbuf, SZ_LINE, Memi[field_pos],
+ nfields, xfield, yfield, xt, yt, nsdig_x, nsdig_y, min_sigdigits)
+
+ call putline (STDOUT, outbuf)
+ }
+
+ call sfree (sp)
+ call close (in)
+end
+
+
+# LT_FIND_FIELDS -- This procedure finds the starting column for each field
+# in the input line. These column numbers are returned in the array
+# field_pos; the number of fields is also returned.
+
+procedure lt_find_fields (linebuf, field_pos, max_fields, nfields)
+
+char linebuf[SZ_LINE]
+int field_pos[max_fields],max_fields, nfields
+bool in_field
+int ip, field_num
+
+begin
+ field_num = 1
+ field_pos[1] = 1
+ in_field = false
+
+ for (ip=1; linebuf[ip] != '\n' && linebuf[ip] != EOS; ip=ip+1) {
+ if (! IS_WHITE(linebuf[ip]))
+ in_field = true
+ else if (in_field) {
+ in_field = false
+ field_num = field_num + 1
+ field_pos[field_num] = ip
+ }
+ }
+
+ field_pos[field_num+1] = ip
+ nfields = field_num
+end
+
+
+# LT_GET_NUM -- The field entry is converted from character to double
+# in preparation for the transformation. The number of significant
+# digits is counted and returned as an argument; the number of chars in
+# the number is returned as the function value.
+
+int procedure lt_get_num (linebuf, dval, nsdig)
+
+char linebuf[SZ_LINE]
+int nsdig
+double dval
+char ch
+int nchar, ip
+
+int gctod()
+
+begin
+ ip = 1
+ nsdig = 0
+ nchar = gctod (linebuf, ip, dval)
+ if (nchar == 0 || IS_INDEFD(dval))
+ return (nchar)
+
+ # Skip leading white space.
+ ip = 1
+ repeat {
+ ch = linebuf[ip]
+ if (! IS_WHITE(ch))
+ break
+ ip = ip + 1
+ }
+
+ # Count signifigant digits
+ for (; ! IS_WHITE(ch) && ch != '\n' && ch != EOS; ch=linebuf[ip]) {
+ if (IS_DIGIT (ch))
+ nsdig = nsdig + 1
+ ip = ip + 1
+ }
+ return (nchar)
+end
+
+
+# LT_TRANSFORM -- The linear transformation is performed in this procedure.
+# First the coordinates are scaled, then rotated and translated. The
+# transformed coordinates are returned.
+
+procedure lt_transform (x, y, xt, yt, tr)
+
+double x, y, xt, yt
+pointer tr
+double xtemp, ytemp
+
+begin
+ # Subtract off current origin:
+ if (IS_INDEFD (x))
+ xt = INDEFD
+ else {
+ xt = x - X1(tr)
+ }
+ if (IS_INDEFD (y))
+ yt = INDEFD
+ else {
+ yt = y - Y1(tr)
+ }
+
+ # Scale and rotate coordinates:
+ if (THETA(tr) == 0) {
+ if (!IS_INDEFD (xt))
+ xt = xt * XSCALE(tr) + X2(tr)
+ if (!IS_INDEFD (yt))
+ yt = yt * YSCALE(tr) + Y2(tr)
+ return
+
+ } else if (IS_INDEFD(xt) || IS_INDEFD(yt)) {
+ # Non-zero angle and either coordinate indefinite results in
+ # both transformed coordinates = INDEFD
+ xt = INDEFD
+ yt = INDEFD
+ return
+ }
+
+ # Rotation for non-zero angle and both coordinates defined
+ xtemp = xt * XSCALE(tr)
+ ytemp = yt * YSCALE(tr)
+
+ xt = xtemp * COS_THETA(tr) - ytemp * SIN_THETA(tr)
+ yt = xtemp * SIN_THETA(tr) + ytemp * COS_THETA(tr)
+
+ # Now shift the rotated coordinates
+ xt = xt + X2(tr)
+ yt = yt + Y2(tr)
+end
+
+
+# LT_PACK_LINE -- Fields are packed into the outbuf buffer. Transformed
+# fields are converted to strings; other fields are copied from
+# the input line to output buffer.
+
+procedure lt_pack_line (inbuf, outbuf, maxch, field_pos, nfields,
+ xfield, yfield, xt, yt, nsdig_x, nsdig_y, min_sigdigits)
+
+char inbuf[ARB], outbuf[maxch]
+int maxch, field_pos[ARB], nfields, xfield, yfield, nsdig_x, nsdig_y
+int min_sigdigits
+double xt, yt
+
+char field[SZ_LINE]
+int num_field, width, op
+
+int gstrcpy()
+
+begin
+ # Initialize output pointer.
+ op = 1
+
+ do num_field = 1, nfields {
+ width = field_pos[num_field + 1] - field_pos[num_field]
+
+ if (num_field == xfield) {
+ call lt_format_field (xt, field, maxch, nsdig_x, width,
+ min_sigdigits)
+ } else if (num_field == yfield) {
+ call lt_format_field (yt, field, maxch, nsdig_y, width,
+ min_sigdigits)
+ } else {
+ # Put "width" characters from inbuf into field
+ call strcpy (inbuf[field_pos[num_field]], field, width)
+ }
+
+ # Fields must be delimited by at least one blank.
+ if (num_field > 1 && !IS_WHITE (field[1])) {
+ outbuf[op] = ' '
+ op = op + 1
+ }
+
+ # Copy "field" to output buffer.
+ op = op + gstrcpy (field, outbuf[op], maxch)
+ }
+
+ outbuf[op] = '\n'
+ outbuf[op+1] = EOS
+end
+
+
+# LT_FORMAT_FIELD -- A transformed coordinate is written into a string
+# buffer. The output field is of (at least) the same width and significance
+# as the input list entry.
+
+procedure lt_format_field (dval, wordbuf, maxch, nsdig, width, min_sigdigits)
+
+char wordbuf[maxch]
+int width, nsdig, maxch, min_sigdigits
+double dval
+
+begin
+ call sprintf (wordbuf, maxch, "%*.*g")
+ call pargi (width)
+ call pargi (max (min_sigdigits, nsdig))
+ call pargd (dval)
+end
diff --git a/pkg/lists/lists.cl b/pkg/lists/lists.cl
new file mode 100644
index 00000000..aec80ded
--- /dev/null
+++ b/pkg/lists/lists.cl
@@ -0,0 +1,20 @@
+#{ Package script task for the LISTS package, a collection of routines
+# for processing textual lists.
+
+package lists
+
+set lists = "pkg$lists/"
+
+task table,
+ tokens,
+ columns,
+ unique,
+ lintran,
+ $rgcursor,
+ rimcursor,
+ words = "lists$x_lists.e"
+
+task average = "lists$average.cl"
+task raverage = "lists$raverage.cl"
+
+clbye()
diff --git a/pkg/lists/lists.hd b/pkg/lists/lists.hd
new file mode 100644
index 00000000..fb1a79a0
--- /dev/null
+++ b/pkg/lists/lists.hd
@@ -0,0 +1,14 @@
+# Help directory for the LISTS (list processing) package.
+
+$doc = "pkg$lists/doc/"
+
+average hlp = doc$average.hlp, src = average.cl
+columns hlp = doc$columns.hlp, src = columns.x
+lintran hlp = doc$lintran.hlp, src = lintran.x
+raverage hlp = doc$raverage.hlp, src = raverage.cl
+rgcursor hlp = doc$rgcursor.hlp, src = rgcursor.x
+rimcursor hlp = doc$rimcursor.hlp, src = rimcursor.x
+table hlp = doc$table.hlp, src = table.x
+tokens hlp = doc$tokens.hlp, src = tokens.x
+unique hlp = doc$unique.hlp, src = unique.x
+words hlp = doc$words.hlp, src = words.x
diff --git a/pkg/lists/lists.men b/pkg/lists/lists.men
new file mode 100644
index 00000000..b3df7b77
--- /dev/null
+++ b/pkg/lists/lists.men
@@ -0,0 +1,10 @@
+ average - Compute the mean and standard deviation of a list
+ columns - Convert multicolumn file to separate files
+ lintran - Perform linear transformation of a list
+ raverage - Running average, standard deviation, and envelope
+ rgcursor - Read the graphics cursor (makes a list)
+ rimcursor - Read the image display cursor (makes a list)
+ table - Format a list of words into a table
+ tokens - Break a file up into a stream of tokens
+ unique - Delete redundant elements from a list
+ words - Break a file up into a stream of words
diff --git a/pkg/lists/lists.par b/pkg/lists/lists.par
new file mode 100644
index 00000000..80cfec6e
--- /dev/null
+++ b/pkg/lists/lists.par
@@ -0,0 +1,4 @@
+# Dummy package parameter file.
+
+version,s,h,"release_date_of_package"
+mode,s,h,ql
diff --git a/pkg/lists/mkpkg b/pkg/lists/mkpkg
new file mode 100644
index 00000000..ca6a80f6
--- /dev/null
+++ b/pkg/lists/mkpkg
@@ -0,0 +1,32 @@
+# Make the LISTS package.
+
+$call relink
+$exit
+
+update:
+ $call relink
+ $call install
+ ;
+
+relink:
+ $set LIBS = "-lxtools -lds"
+
+ $update libpkg.a
+ $omake x_lists.x
+ $link x_lists.o libpkg.a $(LIBS) -o xx_lists.e
+ ;
+
+install:
+ $move xx_lists.e bin$x_lists.e
+ ;
+
+libpkg.a:
+ columns.x
+ lintran.x <ctype.h> <pattern.h>
+ rgcursor.x
+ rimcursor.x <mach.h> <mwset.h>
+ table.x <ctype.h>
+ tokens.x <ctotok.h>
+ unique.x
+ words.x
+ ;
diff --git a/pkg/lists/raverage.cl b/pkg/lists/raverage.cl
new file mode 100644
index 00000000..da350bdd
--- /dev/null
+++ b/pkg/lists/raverage.cl
@@ -0,0 +1,146 @@
+# RAVERAGE -- Running average, standard deviation, and enevelope of a list.
+
+procedure raverage (input, nwin)
+
+file input {prompt="Input file"}
+int nwin {prompt="Number of points in window", min=1}
+bool sort = no {prompt="Sort input?"}
+real nsig = 0 {prompt="Number of sigma for envelope"}
+
+struct *fd1, *fd2
+
+begin
+ file in, tmp
+ int i, j, n, nin
+ real x, y, z, x1, y1, sum1, sum2, sum3, xavg, yavg, sig
+ real ylow, yhigh
+
+ # Get query parameters.
+ in = input
+ nin = nwin
+
+ if (nwin < 1)
+ error (1, "Window size must be greater than zero")
+
+ # Buffer the standard input and sort if requested.
+ tmp = in
+ if (in == "STDIN") {
+ tmp = mktemp ("tmp$iraf")
+ i = 0
+ while (YES) {
+ j = scan(x,y)
+ if (j != 2) {
+ if (j == EOF)
+ break
+ else if (j < 1)
+ next
+ else if (j < 2) {
+ y = x
+ x = i + 1
+ }
+ }
+ i += 1
+ print (x, y, >> tmp)
+ }
+ if (sort) {
+ rename (tmp, tmp//"a")
+ sort (tmp//"a", col=1, num+, rev-, > tmp)
+ delete (tmp//"a", verify-)
+ }
+ } else if (sort) {
+ tmp = mktemp ("tmp$iraf")
+ sort (in,, col=1, num+, rev-, > tmp)
+ }
+
+ # Initialize.
+ i = 0; n = 0; sum1 = 0; sum2 = 0; sum3 = 0
+
+ # Accumulate the first window.
+ fd1 = tmp
+ while (n<nin) {
+ j = fscan (fd1, x, y)
+ if (j != 2) {
+ if (j == EOF)
+ break
+ else if (j < 1)
+ next
+ else if (j < 2) {
+ y = x
+ x = i + 1
+ }
+ }
+ i += 1
+ n += 1
+ sum1 += x
+ sum2 += y
+ sum3 += y*y
+ }
+
+ # Read the rest of the list adding and subtracting.
+ fd2 = tmp
+ while (YES) {
+ j = fscan (fd1, x, y)
+ if (j != 2) {
+ if (j == EOF)
+ break
+ else if (j == 0)
+ next
+ else if (j == 1) {
+ y = x
+ x = i + 1
+ }
+ }
+
+ while (YES) {
+ j = fscan(fd2, x1, y1)
+ if (j != 2) {
+ if (j == 0)
+ next
+ else if (j == 1) {
+ y1 = x1
+ x1 = i - n + 1
+ }
+ }
+ break
+ }
+
+ xavg = sum1 / n
+ yavg = sum2 / n
+ sig = sqrt (max (0., (n * sum3 - sum2 * sum2) / (n * max(1,n-1))))
+ if (nsig > 0) {
+ ylow = yavg - nsig * sig
+ yhigh = yavg + nsig * sig
+ printf ("%g %g %g %d %g %g\n", xavg, yavg, sig, n, ylow, yhigh)
+ } else
+ printf ("%g %g %g %d\n", xavg, yavg, sig, n)
+
+ i += 1
+ sum1 += x - x1
+ sum2 += y - y1
+ sum3 += y*y - y1*y1
+ }
+ fd1 = ""; fd2 = ""
+
+ # Compute the final values.
+ if (n <= 0) {
+ xavg = INDEF
+ yavg = INDEF
+ sig = INDEF
+ ylow = INDEF
+ yhigh = INDEF
+ } else {
+ xavg = sum1 / n
+ yavg = sum2 / n
+ sig = sqrt (max (0., (n * sum3 - sum2 * sum2) / (n * max(1,n-1))))
+ ylow = yavg - nsig * sig
+ yhigh = yavg + nsig * sig
+ }
+ if (nsig > 0)
+ printf ("%g %g %g %d %g %g\n", xavg, yavg, sig, n, ylow, yhigh)
+ else
+ printf ("%g %g %g %d\n", xavg, yavg, sig, n)
+
+ # Delete temporary files.
+ if (tmp != in)
+ delete (tmp, verify-)
+end
diff --git a/pkg/lists/rgcursor.x b/pkg/lists/rgcursor.x
new file mode 100644
index 00000000..d443dba7
--- /dev/null
+++ b/pkg/lists/rgcursor.x
@@ -0,0 +1,27 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+# T_RGCURSOR -- Copy the graphics cursor list to the standard output. This
+# task was originally written as a cl script.
+
+procedure t_rgcursor
+
+pointer sp, buf, gp
+pointer gopen()
+int clglstr()
+
+begin
+ call smark (sp)
+ call salloc (buf, SZ_LINE, TY_CHAR)
+
+ iferr (gp = gopen ("stdgraph", APPEND, STDGRAPH))
+ gp = NULL
+
+ while (clglstr ("gcur", Memc[buf], SZ_LINE) != EOF) {
+ call printf ("%s\n")
+ call pargstr (Memc[buf])
+ }
+
+ if (gp != NULL)
+ call gclose (gp)
+ call sfree (sp)
+end
diff --git a/pkg/lists/rimcursor.par b/pkg/lists/rimcursor.par
new file mode 100644
index 00000000..9838ca9f
--- /dev/null
+++ b/pkg/lists/rimcursor.par
@@ -0,0 +1,5 @@
+image,s,a,,,,image to which coordinates should refer
+wcs,s,h,logical,,,output world coordinate system name
+wxformat,s,h,"",,,x coordinate output format
+wyformat,s,h,"",,,y coordinate output format
+cursor,*imcur,h,,,,image cursor
diff --git a/pkg/lists/rimcursor.x b/pkg/lists/rimcursor.x
new file mode 100644
index 00000000..af265007
--- /dev/null
+++ b/pkg/lists/rimcursor.x
@@ -0,0 +1,191 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <mach.h>
+include <mwset.h>
+
+
+# T_RIMCURSOR -- Read the image cursor list until EOF is seen on the list,
+# transforming the coordinates to the desired system and printing the
+# transformed cursor reads on the standard output.
+
+procedure t_rimcursor()
+
+double px, py, wx, wy
+pointer gp, ct, mw, sp, wcs, rest, format[2], fmt[2]
+int axis, frame, newframe, ntokens, wcscode
+pointer gopen(), rim_getctran()
+int clscan(), nscan()
+errchk gopen, rim_getctran
+
+begin
+ # Allocate working space.
+ call smark (sp)
+ call salloc (wcs, SZ_FNAME, TY_CHAR)
+ call salloc (rest, SZ_LINE, TY_CHAR)
+ do axis = 1, 2 {
+ call salloc (format[axis], SZ_FNAME, TY_CHAR)
+ call salloc (fmt[axis], SZ_FNAME, TY_CHAR)
+ }
+
+ # Open graphics context (doesn't work currently for stdimage).
+ iferr (gp = gopen ("stdimage", APPEND, STDIMAGE))
+ gp = NULL
+
+ # Initialize.
+ frame = 1
+ mw = NULL
+ ct = NULL
+ call clgstr ("wxformat", Memc[format[1]], SZ_FNAME)
+ call clgstr ("wyformat", Memc[format[2]], SZ_FNAME)
+
+ # Read the cursor repeatedly until EOF is seen.
+ while (clscan ("cursor") != EOF) {
+
+ # Get cursor value.
+ call gargd (px)
+ call gargd (py)
+ call gargi (wcscode)
+ newframe = wcscode / 100
+ call gargstr (Memc[rest], SZ_LINE)
+
+ # Get coordinate transformation.
+ ntokens = nscan()
+ if (ntokens < 2)
+ call error (1, "bad cursor read")
+ else if (mw == NULL || (ntokens >= 3 && newframe != frame)) {
+
+ if (mw != NULL)
+ call mw_close (mw)
+ ct = rim_getctran (newframe, Memc[wcs], mw)
+ if (mw != NULL)
+ call mw_ssystem (mw, Memc[wcs])
+ frame = newframe
+
+ do axis = 1, 2 {
+ if (Memc[format[axis]] != EOS)
+ call strcpy (Memc[format[axis]], Memc[fmt[axis]],
+ SZ_FNAME)
+ else if (mw != NULL) {
+ iferr (call mw_gwattrs (mw, axis, "format",
+ Memc[fmt[axis]], SZ_FNAME))
+ call strcpy ("%0.15g", Memc[fmt[axis]], SZ_FNAME)
+ } else
+ call strcpy ("%0.15g", Memc[fmt[axis]], SZ_FNAME)
+ }
+ }
+
+ # Transform coordinates.
+ if (ct != NULL)
+ call mw_c2trand (ct, px,py, wx,wy)
+ else {
+ wx = px
+ wy = py
+ }
+
+ # Always output transformed coordinates.
+ do axis = 1, 2 {
+
+ # Output the transformed value.
+ if (axis == 1) {
+ call fprintf (STDOUT, Memc[fmt[axis]])
+ call pargd (wx)
+ } else {
+ call fprintf (STDOUT, Memc[fmt[axis]])
+ call pargd (wy)
+ }
+
+ call putci (STDOUT, ' ')
+ }
+
+ # Output WCS field if present in input.
+ if (ntokens > 2) {
+ call fprintf (STDOUT, "%d")
+ call pargi (wcscode)
+ }
+
+ # Output rest of cursor value if present in input.
+ if (ntokens > 3)
+ call putline (STDOUT, Memc[rest])
+
+ call putci (STDOUT, '\n')
+ }
+
+ # Shutdown.
+ if (mw != NULL)
+ call mw_close (mw)
+ if (gp != NULL)
+ call gclose (gp)
+ call sfree (sp)
+end
+
+
+# RIM_GETCTRAN -- Get the WCS context to be used for coordinate transforms.
+# Determine the reference image, load the WCS, and compile a transform from
+# logical image coordinates to the desired coordinate system.
+
+pointer procedure rim_getctran (frame, wcs, mw)
+
+int frame #I image frame, if display is used
+char wcs[ARB] #O name of requested wcs
+pointer mw #O MWCS descriptor
+
+int status
+bool use_display
+pointer sp, imname, ds, iw, im, ct
+pointer imd_mapframe(), iw_open(), immap(), mw_sctran(), mw_openim()
+errchk imd_mapframe, iw_open, immap, mw_sctran, mw_openim
+int envfind(), clgeti()
+bool streq()
+
+begin
+ call smark (sp)
+ call salloc (imname, SZ_LINE, TY_CHAR)
+
+ # Access image display to get name of reference image?
+ if (clgeti ("$nargs") > 0)
+ use_display = false
+ else if (envfind ("stdimcur", Memc[imname], SZ_LINE) > 0)
+ use_display = streq (Memc[imname], "stdimage")
+ else
+ use_display = false
+
+ # Get the name of the reference image.
+ if (use_display) {
+ ds = imd_mapframe (frame, READ_ONLY, NO)
+ iw = iw_open (ds, frame, Memc[imname], SZ_LINE, status)
+ call iw_close (iw)
+ call imunmap (ds)
+ } else
+ call clgstr ("image", Memc[imname], SZ_LINE)
+
+ # Map the image if one was specified.
+ if (Memc[imname] == EOS)
+ im = NULL
+ else iferr (im = immap (Memc[imname], READ_ONLY, 0))
+ im = NULL
+
+ # Get WCS if image was given.
+ if (im == NULL) {
+ mw = NULL
+ ct = NULL
+ wcs[1] = EOS
+ } else {
+ ifnoerr (mw = mw_openim (im)) {
+ call clgstr ("wcs", wcs, SZ_FNAME)
+ if (wcs[1] == EOS)
+ call strcpy ("logical", wcs, SZ_FNAME)
+ ct = mw_sctran (mw, "logical", wcs, 03B)
+ } else {
+ mw = NULL
+ ct = NULL
+ }
+
+ # We don't need the image once the WCS is loaded.
+ call imunmap (im)
+ if (mw != NULL)
+ call mw_seti (mw, MW_REFIM, NULL)
+ }
+
+ call sfree (sp)
+ return (ct)
+end
diff --git a/pkg/lists/table.par b/pkg/lists/table.par
new file mode 100644
index 00000000..56781c06
--- /dev/null
+++ b/pkg/lists/table.par
@@ -0,0 +1,5 @@
+input_files,s,a,,,,list of files to be formatted as tables
+first_col,i,h,7,0,,offset to first column of table
+last_col,i,h,0,0,,offset to last column of table (0 for right margin)
+ncols,i,h,0,0,,number of columns (0 to get max that will fit)
+maxstrlen,i,h,0,0,,maximum string length for table entry (0 if none)
diff --git a/pkg/lists/table.x b/pkg/lists/table.x
new file mode 100644
index 00000000..75e0a3e3
--- /dev/null
+++ b/pkg/lists/table.x
@@ -0,0 +1,111 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <ctype.h>
+
+# Read a list of strings from the standard input or a list of files and
+# assemble them into a nicely formatted table. If reading from multiple
+# input files, make a separate table for each. There is no fixed limit
+# to the size of the table which can be formatted. The table is not
+# sorted; this should be done as a separate operation if desired.
+
+define INIT_STRBUF 512
+define STRBUF_INCREMENT 1024
+define INIT_MAXSTR 64
+define MAXSTR_INCREMENT 128
+
+
+procedure t_table()
+
+int list, first_col, last_col, ncols, maxstrlen
+int fd, nextch, nstrings, maxch, sz_strbuf, max_strings, ip
+pointer sp, strbuf, fname, stroff
+int strlen(), fscan(), nscan(), clpopni()
+int clgfil(), open(), envgeti(), clplen(), clgeti()
+
+begin
+ # Allocate buffers. The string buffer "strbuf", and associated list
+ # of offsets "stroff" will be reallocated later if they fill up.
+ call smark (sp)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+
+ call malloc (strbuf, INIT_STRBUF, TY_CHAR)
+ call malloc (stroff, INIT_MAXSTR, TY_INT)
+
+
+ # Get various table formatting parameters from CL.
+ ncols = clgeti ("ncols")
+ first_col = clgeti ("first_col")
+ last_col = clgeti ("last_col")
+
+ # Attempt to read the terminal x-dimension from the environment,
+ # if the user did not specify a valid "last_col". No good reason
+ # to abort if cannot find environment variable.
+ if (last_col == 0)
+ iferr (last_col = envgeti ("ttyncols"))
+ last_col = 80
+
+ # Set maximum string length to size of an output line if max length
+ # not given.
+ maxstrlen = clgeti ("maxstrlen")
+ if (maxstrlen == 0)
+ maxch = last_col - first_col + 1
+ else
+ maxch = min (maxstrlen, last_col - first_col + 1)
+
+ max_strings = INIT_MAXSTR
+ sz_strbuf = INIT_STRBUF
+
+
+ # Read the contents of each file into a big string buffer. Print a
+ # separate table for each file.
+
+ list = clpopni ("input_files")
+
+ while (clgfil (list, Memc[fname], SZ_FNAME) != EOF) {
+ fd = open (Memc[fname], READ_ONLY, TEXT_FILE)
+ nextch = 1
+ nstrings = 0
+
+ # If printing several tables, label each with the name of the file.
+ if (clplen (list) > 1) {
+ call printf ("\n==> %s <==\n")
+ call pargstr (Memc[fname])
+ }
+
+ while (fscan (fd) != EOF) {
+ call gargstr (Memc[strbuf+nextch-1], maxch)
+ # Ignore blank lines and faulty scans.
+ if (nscan() == 0)
+ next
+ for (ip=strbuf+nextch-1; IS_WHITE (Memc[ip]); ip=ip+1)
+ ;
+ if (Memc[ip] == '\n' || Memc[ip] == EOS)
+ next
+
+ # Save one indexed string index for strtbl.
+ Memi[stroff+nstrings] = nextch
+ nextch = nextch + strlen (Memc[strbuf+nextch-1]) + 1
+
+ # Check buffers, make bigger if necessary.
+ if (nextch + maxch >= sz_strbuf) {
+ sz_strbuf = sz_strbuf + STRBUF_INCREMENT
+ call realloc (strbuf, sz_strbuf, TY_CHAR)
+ }
+ # Add space for more string offsets if too many strings.
+ nstrings = nstrings + 1
+ if (nstrings > max_strings) {
+ max_strings = max_strings + MAXSTR_INCREMENT
+ call realloc (stroff, max_strings, TY_INT)
+ }
+ }
+
+ # Print the table on the standard output.
+ call strtbl (STDOUT, Memc[strbuf], Memi[stroff], nstrings,
+ first_col, last_col, maxch, ncols)
+ }
+
+ call clpcls (list)
+ call mfree (strbuf, TY_CHAR)
+ call mfree (stroff, TY_INT)
+ call sfree (sp)
+end
diff --git a/pkg/lists/tokens.par b/pkg/lists/tokens.par
new file mode 100644
index 00000000..1df3490b
--- /dev/null
+++ b/pkg/lists/tokens.par
@@ -0,0 +1,5 @@
+files,s,a,,,,list of files to be converted into a stream of tokens
+ignore_comments,b,h,yes,,,ignore comments in the input stream?
+begin_comment,s,h,"#",,,string marking start of a comment
+end_comment,s,h,"eol",,,"string marking end of a comment ('eol' if end of line)"
+newlines,b,h,yes,,,is newline a legal token?
diff --git a/pkg/lists/tokens.x b/pkg/lists/tokens.x
new file mode 100644
index 00000000..c8793748
--- /dev/null
+++ b/pkg/lists/tokens.x
@@ -0,0 +1,140 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <ctotok.h>
+
+.help tokens
+.nf ___________________________________________________________________________
+TOKENS -- Break the input up into a series of tokens. The makeup of the
+various tokens is defined by the FMTIO primitive ctotok, which is not very
+sophisticated, and does not claim to recognize the tokens for any particular
+language (though it does reasonably well for most modern languages). Comments
+can be deleted if desired, and newlines may be passed on to the output as
+tokens.
+
+Comments are delimited by user specified strings. Only strings which are also
+recognized by ctotok() as legal tokens may be used as comment delimiters.
+If newline marks the end of a comment, the end_comment string should be given
+as "eol". Examples of acceptable comment conventions are ("#", eol),
+("/*", "*/"), ("{", "}"), and ("!", eol). Fortran style comments ("^{c}",eol)
+can be stripped by filtering with match beforehand.
+
+Each token is passed to the output on a separate line. Multiple newline
+tokens are compressed to a single token (a blank line). If newline is not
+desired as an output token, it is considered whitespace and serves only to
+delimit tokens.
+.endhelp ______________________________________________________________________
+
+define SZ_COMDELIMSTR 20 # Comment delimiter string.
+
+procedure t_tokens()
+
+bool ignore_comments, comment_delimiter_is_eol
+bool in_comment, pass_newlines
+char begin_comment[SZ_COMDELIMSTR], end_comment[SZ_COMDELIMSTR]
+int fd, list, token, last_token, last_nscan
+pointer sp, fname, tokbuf, outstr, ip, op
+
+bool streq(), clgetb()
+int clpopni(), clgfil(), fscan(), nscan(), open(), ctocc()
+
+begin
+ call smark (sp)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+ call salloc (tokbuf, SZ_LINE, TY_CHAR)
+ call salloc (outstr, SZ_LINE, TY_CHAR)
+
+ # If comments are to be ignored, get comment delimiters.
+ ignore_comments = clgetb ("ignore_comments")
+ if (ignore_comments) {
+ call clgstr ("begin_comment", begin_comment, SZ_COMDELIMSTR)
+ call clgstr ("end_comment", end_comment, SZ_COMDELIMSTR)
+ comment_delimiter_is_eol = streq (end_comment, "eol")
+ } else {
+ # Set begin_comment to null string to ensure that we never
+ # enter skip comment mode. This requires that we check for the
+ # EOS token before the begin_comment token below.
+ begin_comment[1] = EOS
+ }
+
+ # Is newline a token?
+ pass_newlines = clgetb ("newlines")
+
+
+ # Merge all input files into a single stream of tokens on the standard
+ # output.
+ list = clpopni ("files")
+
+ while (clgfil (list, Memc[fname], SZ_FNAME) != EOF) {
+ fd = open (Memc[fname], READ_ONLY, TEXT_FILE)
+ last_token = NULL
+
+ while (fscan (fd) != EOF) {
+ # Break input line into a stream of tokens.
+ repeat {
+ last_nscan = nscan()
+ call gargtok (token, Memc[tokbuf], SZ_LINE)
+
+ # If "nscan" did not increment (actually impossible with
+ # gargtok) the line has been exhausted.
+ if (nscan() == last_nscan)
+ break
+
+ # If busy ignoring a comment, check for delimiter.
+ if (in_comment) {
+ if (comment_delimiter_is_eol &&
+ (token == TOK_NEWLINE || token == TOK_EOS)) {
+ in_comment = false
+ if (pass_newlines && last_token != TOK_NEWLINE) {
+ call printf ("\n")
+ last_token = TOK_NEWLINE
+ }
+ break
+ } else if (streq (Memc[tokbuf], end_comment)) {
+ in_comment = false
+ next
+ } else
+ next
+ }
+
+ # If we get here, we are not processing a comment.
+
+ if (token == TOK_NEWLINE) {
+ if (pass_newlines && last_token != TOK_NEWLINE)
+ call printf ("\n")
+ last_token = TOK_NEWLINE
+ break
+
+ } else if (token == TOK_EOS) {
+ # EOS is not counted as a token (do not set last_token,
+ # do not generate any output).
+ break
+
+ } else if (streq (Memc[tokbuf], begin_comment)) {
+ in_comment = true
+ # Do not change last_token, since comment token
+ # is to be ignored.
+ next
+
+ } else if (token == TOK_STRING) {
+ # Convert control characters into printable
+ # sequences before printing string token.
+ op = outstr
+ for (ip=tokbuf; Memc[ip] != EOS; ip=ip+1)
+ op = op + ctocc (Memc[ip], Memc[op], SZ_LINE)
+ call printf ("\"%s\"\n")
+ call pargstr (Memc[outstr])
+
+ } else { # most tokens
+ call printf ("%s\n")
+ call pargstr (Memc[tokbuf])
+ }
+
+ last_token = token
+ }
+ }
+ call close (fd)
+ }
+
+ call clpcls (list)
+ call sfree (sp)
+end
diff --git a/pkg/lists/unique.par b/pkg/lists/unique.par
new file mode 100644
index 00000000..2a8206da
--- /dev/null
+++ b/pkg/lists/unique.par
@@ -0,0 +1 @@
+files,s,a,,,,list of files to be processed
diff --git a/pkg/lists/unique.x b/pkg/lists/unique.x
new file mode 100644
index 00000000..fcabfe00
--- /dev/null
+++ b/pkg/lists/unique.x
@@ -0,0 +1,46 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+# UNIQUE -- Pass only unique lines from the (presumably sorted) standard
+# input to the standard output. In other words, if a sequence of identical
+# lines are found in the input, only one copy is passed to the output.
+
+procedure t_unique()
+
+int list, fd
+pointer sp, fname, old_line, new_line, temp
+bool streq()
+int getline(), clpopni(), clgfil(), clplen(), open()
+
+begin
+ call smark (sp)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+ call salloc (old_line, SZ_LINE, TY_CHAR)
+ call salloc (new_line, SZ_LINE, TY_CHAR)
+
+ list = clpopni ("files")
+
+ while (clgfil (list, Memc[fname], SZ_FNAME) != EOF) {
+ fd = open (Memc[fname], READ_ONLY, TEXT_FILE)
+ if (clplen (list) > 1) {
+ call printf ("\n\n==> %s <==\n")
+ call pargstr (Memc[fname])
+ }
+
+ Memc[old_line] = EOS
+
+ while (getline (fd, Memc[new_line]) != EOF) {
+ if (streq (Memc[old_line], Memc[new_line]))
+ next
+ call putline (STDOUT, Memc[new_line])
+
+ # Swap buffers.
+ temp = old_line
+ old_line = new_line
+ new_line = temp
+ }
+
+ call close (fd)
+ }
+
+ call sfree (sp)
+end
diff --git a/pkg/lists/words.par b/pkg/lists/words.par
new file mode 100644
index 00000000..513eeb8f
--- /dev/null
+++ b/pkg/lists/words.par
@@ -0,0 +1 @@
+files,s,a,,,,list of files to be converted into a stream of words
diff --git a/pkg/lists/words.x b/pkg/lists/words.x
new file mode 100644
index 00000000..42f4f97e
--- /dev/null
+++ b/pkg/lists/words.x
@@ -0,0 +1,44 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+# WORDS -- Break the input up into a series of words or strings. A word
+# is a sequence of characters delimited by whitespace or newline. A string
+# is delimited by single or double quotes, and may not span more than a single
+# line.
+
+procedure t_words()
+
+int fd, list, last_nscan
+pointer sp, fname, word
+int clpopni(), clgfil(), fscan(), nscan(), open()
+
+begin
+ call smark (sp)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+ call salloc (word, SZ_LINE, TY_CHAR)
+
+ list = clpopni ("files")
+
+ while (clgfil (list, Memc[fname], SZ_FNAME) != EOF) {
+ fd = open (Memc[fname], READ_ONLY, TEXT_FILE)
+
+ # We do not know how may "words" there are on a line; get words
+ # until no more.
+ while (fscan (fd) != EOF)
+ repeat {
+ # When nscan() does not increment after a call to gargwrd(),
+ # we are all done.
+ last_nscan = nscan()
+ call gargwrd (Memc[word], SZ_LINE)
+ if (nscan() > last_nscan) {
+ call printf ("%s\n")
+ call pargstr (Memc[word])
+ } else
+ break
+ }
+
+ call close (fd)
+ }
+
+ call clpcls (list)
+ call sfree (sp)
+end
diff --git a/pkg/lists/x_lists.x b/pkg/lists/x_lists.x
new file mode 100644
index 00000000..bca089b8
--- /dev/null
+++ b/pkg/lists/x_lists.x
@@ -0,0 +1,12 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+# Process configuration of the LISTS package.
+
+task table = t_table,
+ tokens = t_tokens,
+ columns = t_columns,
+ unique = t_unique,
+ words = t_words,
+ lintran = t_lintran,
+ rgcursor = t_rgcursor,
+ rimcursor = t_rimcursor