A program to list files from bottom to top.

Stephen J. Muir stephen at dcl-cs.UUCP
Sat Aug 31 12:03:52 AEST 1985


Here is a program which reverses the order of lines in files.
----------------------------------- cut here ----------------------------------
#!/bin/sh
echo 'Start of pack.out, part 01 of 01:'
echo 'x - revfile.1'
sed 's/^X//' > revfile.1 << '/'
X.TH REVERSE 1  "30 August 1985"
X.SH NAME
Xrevfile \- reverse order of lines in files
X.SH SYNOPSIS
X.B revfile
X[ file ] ...
X.SH DESCRIPTION
X.I Revfile
Xcopies the named files to the standard output, reversing the order of the lines.
XIf no file is specified, the standard input is copied.
XThe filename \*(lq-\*(rq also refers to the standard input.
XLines can be arbitrary length.
X.SH BUGS
XThe effect is irreversible if the last character of the file isn't '\\n',
Xobviously.
X.SH AUTHOR
XStephen J. Muir (dcl-cs!stephen)
/
echo 'x - revfile.c'
sed 's/^X//' > revfile.c << '/'
X/* Written by Stephen J. Muir, Computing Dept., Lancaster University
X * stephen at uk.ac.lancs.comp
X * stephen at uk.ac.lancaster.computing
X * dcl-cs!stephen
X *
X * revfile(1) - reverse order of lines in files
X *
X */
X
X# include <stdio.h>
X# include <sys/types.h>
X# include <sys/stat.h>
X# include <sys/file.h>
X
X# define BUFSIZE	4096
X
Xextern char	*malloc ();
X
Xchar	*standin = "-", *tmpfile = "/tmp/revfileXXXXXX";
X
Xstruct stat	mystat;
X
Xstruct list
X	{ char		l_buf [BUFSIZE];
X	  short		l_cnt;
X	  struct list	*l_next;
X	}	*head, *pool;
X
X/* insert data at beginning of list */
Xlinsert (buf, size)
X	char	*buf;
X	{ register struct list	*lp;
X	  if (size == 0)
X		return;
X	  if (lp = pool)	/* try to reuse a list element */
X		pool = pool->l_next;
X	  else if ((lp = (struct list *)malloc (sizeof (struct list))) == 0)
X	  { fprintf (stderr, "Out of memory\n");
X	    exit (1);
X	  }
X	  bcopy (buf, lp->l_buf, size);
X	  lp->l_cnt = size;
X	  lp->l_next = head;
X	  head = lp;	/* insert at head of list */
X	}
X
Xlflush (buf, size)
X	char	*buf;
X	{ register struct list	*lp;
X	  if (size && fwrite (buf, 1, size, stdout) != size)
X	  { perror ("stdout");
X	    exit (1);
X	  }
X	  while (head)		/* flush list */
X	  { if (fwrite (head->l_buf, 1, head->l_cnt, stdout) != head->l_cnt)
X	    { perror ("stdout");
X	      exit (1);
X	    }
X	    head = (lp = head)->l_next;
X	    lp->l_next = pool;
X	    pool = lp;		/* add to list of old elements */
X	  }
X	}
X
Xrevfile (name)
X	char	*name;
X	{ static char	buf [BUFSIZE];
X	  register char	*cp, *ep;
X	  register int	ofd, nfd, i, pos, newpos;
X	  if (strcmp (name, standin))	/* open the file */
X	  { if ((ofd = open (name, O_RDONLY)) == -1)
X	    { perror (name);
X	      return (1);
X	    }
X	  }
X	  else
X		ofd = 0;
X	  /* attempt to use original file */
X	  if (fstat (ofd, &mystat) == -1 ||
X	      (mystat.st_mode & S_IFMT) != S_IFREG ||	/* regular file? */
X	      (pos = lseek (ofd, 0, L_XTND)) == -1	/* go to EOF? */
X	     )
X	  { pos = 0;				/* failed - copy file */
X	    if ((nfd = open (tmpfile, O_RDWR|O_CREAT, 0)) == -1 ||
X		unlink (tmpfile) == -1
X	       )
X	    { perror (tmpfile);
X	      goto erroro;
X	    }
X	    while ((i = read (ofd, buf, BUFSIZE)) > 0)
X	    { if (write (nfd, buf, i) != i)
X	      { perror (tmpfile);
X		goto errorn;
X	      }
X	      pos += i;
X	    }
X	    if (i == -1)
X	    { perror (name);
X	      goto errorn;
X	    }
X	    close (ofd);
X	    ofd = nfd;
X	    name = tmpfile;
X	  }
X	  while (pos)
X	  { if ((newpos = pos - BUFSIZE) < 0)
X		newpos = 0;
X	    i = pos - newpos;
X	    if (lseek (ofd, newpos, L_SET) != newpos || read (ofd, buf, i) != i)
X	    { perror (name);
X	      goto erroro;
X	    }
X	    for (cp = ep = &buf [i]; cp > &buf [0]; )
X		if (*--cp == '\n')
X		{ lflush (cp + 1, ep - (cp + 1));
X		  ep = cp + 1;
X		}
X	    linsert (cp, ep - cp);
X	    pos = newpos;
X	  }
X	  lflush (0, 0);
X	  if (ofd)
X		close (ofd);
X	  return (0);
Xerrorn:	  close (nfd);
Xerroro:	  if (ofd)
X		close (ofd);
X	  return (1);
X	}
X
X/*ARGSUSED*/
Xmain (argc, argv, envp)
X	char	*argv [], *envp [];
X	{ register short	exitstat = 0;
X	  if (--argc <= 0)
X	  { argv = &standin;
X	    argc = 1;
X	  }
X	  else
X		++argv;
X	  mktemp (tmpfile);
X	  while (argc--)
X		if (revfile (*argv++))
X			exitstat = 1;
X	  if (fclose (stdout) == EOF)
X	  { perror ("stdout");
X	    exit (1);
X	  }
X	  exit (exitstat);
X	}
/
echo 'Part 01 of pack.out complete.'
exit
-- 
UUCP:	...!seismo!mcvax!ukc!dcl-cs!stephen
DARPA:	stephen%lancs.comp at ucl-cs	| Post: University of Lancaster,
JANET:	stephen at uk.ac.lancs.comp	|	Department of Computing,
Phone:	+44 524 65201 Ext. 4599		|	Bailrigg, Lancaster, UK.
Project:Alvey ECLIPSE Distribution	|	LA1 4YR



More information about the Comp.sources.unix mailing list