[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Aztec C SHELLS - Unix-Like Environment for DOS 3.3 and ProDOS 8



Occasionally it is nice to have a sort filter. The ProDOS version of Aztec C 
provides  a qsort both in the shell library and outside of the shell. For 
sure a variation of this will work in DOS 3.3 outside of the SHELL but I 
will work with this some more to see what I can do about plain redirection 
in DOS 3.3 inside the shell.

Not being overly concerned about interoperability, I may not get this 
working to the same level as in Unix, Windows, and ProDOS but I am pretty 
confident the code you see below will be pretty much doable under DOS 3.3.

You will probably note that blank lines are skipped, and I am using variable 
size dynamically allocated memory buffers  in the interests of maintaining a 
modicum of civilized efficiency, but I have stayed with a limit of a maximum 
of 2048 elements for my sort array and a maximum element length of 80 
characters and would argue that most text files that one would want to sort 
will have smaller elements or fewer lines. I hope so because the potential 
here is about 4 times or so more than what an Apple II has, and I wanted to 
stay out of auxilliary memory in case the RAM disk is in use which it is in 
the ProDOS SHELL. For the occasion where this runs out of memory the test 
for mallocation is my sanity check.

Anyway, here's the code. If anyone has written a sort filter in some other C 
on the Apple II feel free to critique this. For one thing, I wonder how 
quickly your redirection would have compared between a native mode and shell 
version using your chosen compiler.

I am working on a bunch of other shell utilities like filters for converting 
Apple II text to IBM-PC text etc. but I will definitely bundle all this when 
done into a new and much improved version of this happy little zip. In the 
meantime this code can be added to your Aztec C FoodChain.

Have Fun!

Bill

x--- snip ---x

/* -------------------------------------------------------------------
 System       : ProDOS 8
 Environment  : Aztec C Shell
 Program      : sort.c
 Description  : Sort filter.

                This program is a sort filter. It optionally accepts
                a filename to read input from. All output goes to the
                standard output device unless redirected.

                Examples:
                  Sort abc.txt
                      read input from abc.txt,
                      output goes to screen.
                  Sort abc.txt >abcnew.txt
                      read input from abc.txt,
                      output goes to abcnew.txt.
                  Sort <abc.txt >abcnew.txt
                      same as previous example

 Written by   : Bill Buckels
 Date Written : Aug 2008
 Revision     : 1.0 First Release
 ------------------------------------------------------------------ */
#include <stdio.h>

char *malloc();
char *gets();
int cmp();

#define MAXLINE   80
#define FEEDTEST  78
#define MAXLINES  2048

FILE *fp = NULL;
char *lines[MAXLINES];
char buf[MAXLINE+1];


main(argc, argv)
int argc;
char **argv;
{
 int idx, c, len=0, numlines = 0;
 char *ptr;

    if (argc > 1)
      fp = fopen(argv[1], "r");

 for (;;)
 {
      if (NULL == fp)
        c = getchar();
      else
        c = fgetc(fp);

   /* nobody should be sorting text lines longer than 80 */
   /* what would be the point? */
   if (c == '\n' || c == '\r' || len > FEEDTEST || c == EOF) {
  if (c != EOF && c != '\n' && c!='\r') {
   buf[len] = c;
   len++;
  }
  /* terminate the buffer */
  if (len != 0) {
   buf[len] = 0;
   len++;
   /* transfer the line into storage */
   ptr = malloc (len);
   if (NULL == ptr)break;
   lines[numlines] = ptr;
   strcpy (lines[numlines], buf);
   numlines++;
   len = 0;
  }
  if (numlines == MAXLINES || c == EOF) {
   break;
  }
   }
   else {
  buf[len] = c;
  len++;
   }
 }
 if (numlines > 1)
   qsort (lines, numlines, 2, cmp);
 for (idx=0; idx<numlines; idx++) printf ("%s\n", lines[idx]);

 if (numlines == 0)putchar('\n');

 if (NULL != fp) {
       fclose(fp);
       exit(0);
    }
}

cmp (a, b)
char **a, **b;
{
 return strcmp (*a, *b);
}