/*   addobs is a keyword written by Alan G. Isaac
**   for public non-commercial use.
**   There are no performance guarantees for this code.
**   Suggestions for extensions are welcome.
**   Last update: 06/20/1995
**
**   Alan G. Isaac
**   Mail:         Department of Economics
**                 The American University
**                 Washington, DC 20016
**                 USA
**   Internet:     aisaac@american.edu
**
**
**    Documentation
**    -------------
**
**    Keyword: addobs
**
**    Purpose: Appends new observations to an existing data set.
**
**    Format: addobs newdata.dat dest.dat [append]
**
**    Input: newdata, the GAUSS data set containing the new observations.
**           dest,    the GAUSS data set to be appended
**                          (or a new data set name).
**           append,  optional parameter specifying the desire to
**                    append observations in newdata to dest.
**                    (Without this option, data is written only
**                    if `dest' will be a new data set, in which
**                    case `newdata' is simply copied to `dest'.)
**     Remarks: i.    `newdata' may contain superfluous variables,
**                    and variable columns need not match between
**                    `newdata' and `dest', but the names of variables
**                    to be appended must match.
**              ii.   If `dest' exists already, it will be appended only
**                    if the `append' option is selected. I recommend
**                    first creating a copy of the old data, especially
**                    if disk capacity is a potential issue.
**              iii.  Do not double any backslashes in the file name.
**                    For example,
**                        addobs c:¢source.dat e:¢dest.dat append;
*/

keyword addobs(str);
    local newdata,dest,opt,dnames,snames,newtype,dtype,
          rowchk,myindx,newfh,destfh,k1,readdata,errmsg;

     {newdata,dest} = token(str);
     {dest,opt} = token(dest);


     if files(newdata,0)==0 and files(newdata$+".dat",0)==0;
       goto errout("Source file `"$+newdata$+"' doesn't exist.");
     endif;

     newfh = -1; destfh = -1;
     open newfh = ^newdata;
     if newfh == -1;
       goto errout(newdata $+ " could not be opened.");
     endif;
     newtype = typef(newfh);

     if files(dest,0)==0 and files(dest$+".dat",0)==0;
       dnames = getname(newdata);
       create  destfh = ^dest with ^dnames,0,newtype;
     elseif upper(opt) $/= "APPEND";
       goto errout("Since `"$+dest$+"' exists, you must use `append' option.");
     else;
       dnames = getname(dest);
       open destfh = ^dest for append;
     endif;
     if destfh == -1;
       goto errout("Cannot open/create `"$+dest$+"' .");
     endif;
     rowchk = rowsf(destfh);
     dtype = typef(destfh);
     if dtype < newtype;
       "Warning: destination file is lower precision than source file.";
       "Any character information will be lost unless double precision.";
     endif;


     snames = getname(newdata);
     myindx = indcv(dnames,snames);
     if ismiss(myindx);
       goto errout("Source data lacks some destination file variables.");
     else;
       print "The destination variable names are: " $dnames';
     endif;


      call seekr(newfh,1); call seekr(destfh,0);
      k1 = getnr(2,colsf(newfh));

      do until eof(newfh);
          readdata = readr(newfh,k1);
          if writer(destfh,readdata[.,myindx]) /= rows(readdata);
           goto errout("Write failure. Disk may be full.");
          endif;
      endo;

      if rowchk+rowsf(newfh) /= rowsf(destfh);
        goto errout("Failure in writing data to `"$+dest$+"' .");
      endif;

      closeall newfh,destfh;
retp;
   errout:
    pop errmsg;
    print "\g";
    errorlog "Error: "$+errmsg;
    closeall newfh,destfh;
endp;
