home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / EDITOR / MG2A_SRC.ZIP / SYS / VMS / FILEIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-23  |  6.4 KB  |  298 lines

  1. /*
  2.  * Name:    MicroGNUEmacs
  3.  * Version:    2a
  4.  *        VAX/VMS file I/O.
  5.  * Created:    05-Feb-86 decvax!decwrl!dec-rhea!dec-rex!conroy
  6.  * Last edit:    1-Mar-88  sandra@cs.utah.edu
  7.  *
  8.  * Read and write ASCII files on VAX/VMS. All of the low level file
  9.  * I/O knowledge is here.  This uses RMS system calls directly because
  10.  * the VAX C i/o functions are so slow.
  11.  */
  12.  
  13. #include    "def.h"
  14. #include    <rms.h>
  15. #define DEFAULT_READ_BUFFER_SIZE 1024
  16.  
  17. struct FAB fab;
  18. struct RAB rab;
  19. struct XABFHC xab;
  20. char *inbuf;
  21. int instart, inend;
  22.  
  23.  
  24. /*
  25.  * Open a file for reading.  Also malloc's an input buffer that is big enough
  26.  *    to hold the longest line in the file.  
  27.  */
  28. ffropen(fn)
  29. char    *fn;
  30. {
  31.     int maxlen;
  32.  
  33.     fab = cc$rms_fab;
  34.     rab = cc$rms_rab;
  35.     xab = cc$rms_xabfhc;
  36.         fab.fab$l_fna = fn;
  37.     fab.fab$b_fns = strlen(fn);
  38.     fab.fab$l_xab = &xab;
  39.     rab.rab$l_fab = &fab;
  40.     rab.rab$w_isi = 0;
  41.     if (SYS$OPEN (&fab, 0, 0) == RMS$_NORMAL)  {
  42.         SYS$CONNECT (&rab, 0, 0);
  43.         if (xab.xab$w_lrl == 0)
  44.             maxlen = DEFAULT_READ_BUFFER_SIZE;
  45.          else 
  46.             maxlen = xab.xab$w_lrl;
  47.         inbuf = malloc(maxlen);
  48.         instart = 0;
  49.         inend = 0;
  50.         rab.rab$l_ubf = inbuf;
  51.         rab.rab$w_usz = maxlen;
  52.         return (FIOSUC);
  53.         }
  54.     else
  55.         return (FIOFNF);
  56. }
  57.  
  58. /*
  59.  * Open a file for writing.
  60.  * Return TRUE if all is well, and
  61.  * FALSE on error (cannot create).
  62.  */
  63. ffwopen(fn)
  64. char    *fn;
  65. {
  66.     int status;
  67.  
  68.     fab = cc$rms_fab;
  69.     rab = cc$rms_rab;
  70.         fab.fab$l_fna = fn;
  71.     fab.fab$b_fns = strlen(fn);
  72.     fab.fab$b_rat = FAB$M_CR;
  73.     fab.fab$b_rfm = FAB$C_VAR;
  74.     rab.rab$l_fab = &fab;
  75.     rab.rab$w_isi = 0;
  76.         status = SYS$CREATE (&fab, 0, 0);
  77.         switch (status) {
  78.  
  79.           case RMS$_NORMAL:
  80.           case RMS$_FILEPURGED:
  81.                 SYS$CONNECT (&rab, 0, 0);
  82.         inbuf = NULL;
  83.         return (FIOSUC);
  84.  
  85.           default:
  86.                 ewprintf("Cannot open file for writing STS=%d, STV=%d",
  87.                          fab.fab$l_sts, fab.fab$l_stv);
  88.                 return (FIOERR);
  89.         }
  90. }
  91.  
  92. /*
  93.  * Close a file.
  94.  */
  95. ffclose()
  96. {
  97.         if (inbuf)
  98.         free(inbuf);
  99.         if (SYS$CLOSE(&fab, 0, 0) == RMS$_NORMAL)
  100.         return (FIOSUC);
  101.     else
  102.         return (FIOERR);
  103. }
  104.  
  105. /*
  106.  * Write a buffer to the already opened file. bp points to the
  107.  * buffer. Return the status.
  108.  * This doesn't write out the last line of the buffer unless it is
  109.  * non-empty, to prevent VMS from putting an extra newline at the
  110.  * end of the file.
  111.  */
  112.  
  113. ffputbuf(bp)
  114. BUFFER *bp;
  115. {
  116.     register LINE *lp;
  117.     register LINE *lpend;
  118.     int status;
  119.  
  120.     lpend = bp->b_linep;
  121.     lp = lforw(lpend);
  122.     while (! ((lp == lpend) || ((lforw(lp) == lpend) && (llength(lp) == 0))))  {
  123.         rab.rab$l_rbf = <ext(lp)[0];
  124.     rab.rab$w_rsz = llength(lp);
  125.     if ((status = SYS$PUT (&rab, 0, 0)) != RMS$_NORMAL)  {
  126.         ewprintf("Write I/O error, VMS status code %d", status);
  127.         return(FIOERR);
  128.         }
  129.     lp = lforw(lp);
  130.     }
  131.     return FIOSUC;
  132. }
  133.  
  134. /*
  135.  * Read a line from a file, and store the bytes in the
  136.  * supplied buffer. Stop on end of file or end of line.
  137.  * Returns an extra newline on FIOEOF.
  138.  *
  139.  */
  140.  
  141. ffgetline(buf, nbuf, nbytes)
  142. register char    *buf;
  143. register int    nbuf;
  144. register int    *nbytes;
  145.  
  146. {    register int status;
  147.     register int i;
  148.  
  149.  
  150.         /* Load the input buffer if it's empty.  */
  151.  
  152.         if (instart >= inend)  {
  153.         status = SYS$GET (&rab, 0, 0);
  154.         if (status == RMS$_EOF)  {
  155.             *nbytes = 0;
  156.         return FIOEOF;
  157.         }
  158.         else if (status != RMS$_NORMAL)  {
  159.               ewprintf("File read error, VMS status code %d", status);
  160.             return FIOERR;
  161.             }
  162.         else {
  163.             instart = 0;
  164.             inend = rab.rab$w_rsz;
  165.         }
  166.         }
  167.  
  168.         /* Copy contents of the input buffer */
  169.  
  170.     *nbytes = inend - instart;
  171.         if (*nbytes > nbuf) *nbytes = nbuf;
  172.     for (i=0; i<*nbytes; i++)
  173.         buf[i] = inbuf[instart++];
  174.     if (instart < inend)
  175.         return FIOLONG;
  176.     else
  177.         return FIOSUC;
  178.  
  179. }
  180.  
  181. #ifndef    NO_BACKUP
  182. /*
  183.  * VMS has version numbers, so there is no need for
  184.  * MicroEMACS to bother making its own flavour of
  185.  * backup copy. Return TRUE so the caller doesn't quit.
  186.  */
  187. fbackupfile(fname)
  188. char    *fname;
  189. {
  190.     return (TRUE);
  191. }
  192. #endif
  193.  
  194. /*
  195.  * The string "fn" is a file name. Canonicalize it by making RMS
  196.  * do the dirty work, then lowercase it.
  197.  */
  198. char *adjustname(fn)
  199. char    *fn;
  200. {
  201.     register char *cp;
  202. #ifndef    NO_DIR
  203.     char *fullname, *fparse(), *strrchr();
  204.     static char name[NFILEN];
  205.  
  206.     if (fullname = fparse(fn, NULL, NULL, NULL)) {
  207.         strncpy(name, fullname, NFILEN);
  208.         fn = name;
  209.         free(fullname);    /* fparse malloc()'s the name */
  210.     }
  211. #endif
  212.     for (cp = fn; *cp ; cp++)
  213.         if (ISUPPER(*cp))
  214.             *cp = *cp - 'A' + 'a';
  215.     return fn;
  216. }
  217.  
  218. /*
  219.  * Fn1 and Fn2 are two file names. Return 0 if they represent the
  220.  * same file.
  221.  * Both arguments have already gone through adjustname(), so just do
  222.  * strcmp() here.
  223.  */
  224. fncmp(fn1,fn2)
  225. char *fn1,*fn2;
  226. {
  227.     return strcmp(fn1,fn2);
  228. }
  229.  
  230. #ifndef    NO_STARTUP
  231. #include <file.h>
  232. /*
  233.  * Find the user's startup file, and return its name.
  234.  */
  235. char *
  236. startupfile(suffix)
  237. char *suffix;
  238. {
  239.     static char    file[NFILEN];
  240.  
  241.         (VOID) strcpy(file, "SYS$LOGIN:.MG");
  242.         if (suffix)  {
  243.         strcat(file,"-");
  244.         strcat(file,suffix);
  245.     }
  246.     if (access(file, O_RDONLY ) == 0) return file;
  247.     return NULL;
  248. }
  249. #endif
  250.  
  251. #ifndef NO_DIR
  252. #include <descrip.h>
  253. #include <ssdef.h>
  254.  
  255. /*
  256.  * Get current working directory.  Path had best be rather big
  257.  * (at least 400 characters long...)
  258.  */
  259.  
  260. $DESCRIPTOR(sys_disk,"SYS$DISK");
  261.  
  262. char *getwd(path)
  263. char path[];
  264. {
  265.     struct    dsc$descriptor    devdsc, dirdsc;
  266.     char     tempdev[512], tempdir[512];
  267.     int    status, templen;
  268.     short    devlen, dirlen;
  269.  
  270.     /* translate the logical name SYS$DISK */
  271.  
  272.     devdsc.dsc$a_pointer = tempdev;
  273.     devdsc.dsc$w_length  = sizeof(tempdev) - 1;
  274.     devdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  275.     devdsc.dsc$b_class   = DSC$K_CLASS_S;
  276.     
  277.     status = LIB$SYS_TRNLOG(&sys_disk, &devlen, &devdsc);
  278.     if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  279.         panic("getwd: can't translate SYS$DISK");
  280.  
  281.     /* Append the current default directory using SYS$SETDDIR() */
  282.  
  283.     dirdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  284.     dirdsc.dsc$b_class   = DSC$K_CLASS_S;
  285.     dirdsc.dsc$a_pointer = tempdir;
  286.     dirdsc.dsc$w_length  = sizeof(tempdir) - 1;
  287.  
  288.     status = SYS$SETDDIR(0L, &dirlen, &dirdsc);
  289.     if (status != RMS$_NORMAL)
  290.         panic("getwd: can't get current directory!");
  291.  
  292.     bcopy(tempdev,path,devlen);
  293.     bcopy(tempdir,path+devlen,dirlen);
  294.     path[devlen + dirlen] = '\0';
  295.     return path;
  296. }
  297. #endif
  298.