[mod.os.os9] OS-9 Discussions, V2 #7

os9@cbosgd.att.com (12/02/86)

OS-9 Discussions         Monday, December 1st 1986         Volume 2 : Issue 7

Today's Topics:

                                    BYTE: UK
                              Unshar, MicroGnuEmacs

--------------------------------------------------------------------------

From: mcrware!jejones (James Jones)
Date: 22 Nov 1986 1435-CST (Saturday)
Subject: BYTE: UK

Gee...OS-9 got mentioned in BYTE again, this time in "BYTE: UK",
concerning the U-MAN 1000.  The two paragraphs are sufficiently
short that I include the full text:

	"OS-9, an operating system originally written for
	the 6809 microprocessor, inspires almost fanatical
	devotion among its followers  [That's funny; Jerry
	Pournelle said almost exactly the same thing.  Maybe
	we should get some mock-Spanish Inquisition suits
	made :-)]; U-Micro put it onto the U-MAN in response
	to requests from users.  It's a full 68000 version
	and doesn't run on the U-MAN's 6809 [the I/O and
	graphics processor].  OS-9 provides many of the
	features of Unix (indeed, its shell is almost in-
	distinguishable from Unix's), including multitasking
	and multiuser operation. However, OS-9 is capable of
	responding to peripherals in real time, a feat that
	Unix's virtual memory system almost completely
	precludes; under Unix you can never be sure that
	the servicing routine hasn't been swapped out in
	favor of another task.  This feature makes OS-9
	ideal for scientific applications where, for example,
	a background task might be continuously monitoring
	an instrument while the user runs programs to process
	and display the results in the foreground.

	"I had never played with OS-9 before and was
	pleasantly surprised at how nice it is to use.
	It provides all the better features of Unix, like
	pipes, filters, and redirection (rather like a
	grown-up version of DOS 2.0 [them's fightin' words!]),
	and includes a remarkable language called BASIC09.
	This is to Microsoft BASIC as Robert de Niro is to
	Sylvester Stallone (i.e., it approaches things with
	rather more finesse).  It's completely structured,
	the source code looking much like Pascal, and is
	modular to an extraordinary degree, global data
	being forbidden altogether.  Individually named
	procedures can be separately compiled and even run
	and tested from the command line, then called from
	a main program."

Rather a nice description.  (Whoever makes up the blurbs in
large type at the tops of pages seems to have confused OS-9
with BASIC09, so that the blurb says "OS-9 is completely
structured, the source code looking much like Pascal..."
Hard to do in assembler, fer shur! :-)  I may have to go
watch *Raging Bull* and *Rocky n* for some n, to get some
insight into programming languages. :-)

	James Jones

------------------------------
 
From: Bob Larson <sdcrdcf!usc-oberon!blarson>
Subject: Unshar, MicroGnuEmacs
Date: Sat, 29 Nov 86 20:28:47 -0800

Here is an unshar program I wrote to take apart unix shar arcives on
my QT+.  It isn't perfect, but I find it useful.  Unlike other unshar
programs I have seen, it doesn't depend on any unix utilities.  (I'm
posting it here partly due to the 3 week backlog of mod.sources and
partly because I think thef audience here is more approprate.  I
assume the moderator will tell me if he disagrees.) For example, it
would be useful to unshar:

MicroGnuEmacs, (mg) coming soon via mod.sources.  This is a fairly
advanced version of MicroEmacs, compatable with Gnu Emacs as much as
practical.  (It's based on v30, I don't realy know how it compares to
3.7i, I havn't looked into any of Dave Laurence's versions since I
noticed how ugly and buggy 3.6 was compared to v30.)  OSK is one of
the supported systems.

/* unshar.c -- unshar program for os9/68k by Robert A. Larson */
/*
 * This program extracts files from Unix "shar" (shell archive) files.
 * It makes no claim to be anything close to the Bourne shell and the
 * standard unix utilities other than it successfully extracts files
 * from some shar files.  The current version is known to do this with
 * three diffent versions of shar, but it does not always correctly
 * handle the echo command and aborts at the case statement at the end of
 * the shar for Larry Wall's patch.
 * 
 * The OS9/68K specific code is #ifdef'ed under OSK, however there is no
 * non-OSK version for this code.  It will probably also work for
 * os9/6809.  Although this was not written for speed, it is probably
 * faster than the normal technique of running the shar files through the
 * Bourne shell. 
 *
 * If you have improvements to this code to handle additional varieties
 * of shar files, please send them back to blarson@usc-oberon.arpa
 * (sdcrdcf!usc-oberon!blarson).  This software is supplied as-is, and no
 * warentee of anything about it exists.
 *
 * 11/23/86 ral inital version
 */

#include <stdio.h>

#ifdef	OSK
#  include <modes.h>
#endif

#define	strEQ(s1,s2)	(strcmp(s1,s2)==0)
#define strnEQ(s1,s2,n)	(strncmp(s1,s2,n)==0)
#define TRUE	1
#define FALSE	0

#define	MAXLINE	1024			/* maximum line length		*/
#define	MAXCOND	16			/* maximum levels of "if"	*/
#define MAXARG	16			/* maximum number of arguments	*/

static char line[MAXLINE];
static char *eofp = NULL;
static FILE *infile = stdin;
static FILE *outfile = stdout;
static int  cond = 1, cl = 0, condl[MAXCOND];

int nextline()
{
  if(fgets(line, MAXLINE-1, infile)==NULL) return(0);
  if(eofp==NULL || line[0]=='\0') return(1);
  if(strnEQ(line, eofp, strlen(line)-1) && strlen(line)-1 == strlen(eofp)) {
    eofp = NULL;
    return(0);
  }
  return(1);
}

static int clargc;
static char *clargv[MAXARG];

int clparse()
{
  static char cl[MAXLINE];
  register char *cp, *cpb;
  char *mode;
  clargc = 0;
  if(infile!=stdin) {
    fclose(infile);
    infile = stdin;
  }
  if(outfile!=stdout) {
    fclose(outfile);
    outfile = stdout;
  }
  if(fgets(cl, MAXLINE-1, stdin)==NULL) return(0);
  cp = &cl[0];
  if(*cp=='#' || *cp==':') return(1);
  do {
    switch(*cp) {
      case ' ':
      case '\t':
        cp++;
	break;
      case '\0':
      case '\n':
        return(1);
      case '"':
	clargv[clargc++] = ++cp;
	while(*cp!='"' && *cp!='\n') cp++;
	*cp++ = '\0';
	break;
      case '\'':
        clargv[clargc++] = ++cp;
	while(*cp!='\'' && *cp!='\n') cp++;
	*cp++ = '\0';
	break;
      case '<':
        if(*++cp == '<') {
	  while(*++cp==' ' || *cp=='\t') {}
	  switch(*cp) {
	    case '\n':
	      return(1);
	    case '\'':
	      eofp = ++cp;
	      while(*cp!='\'' && *cp!='\n') cp++;
	      *cp++ = '\0';
	      break;
	    case '"':
	      eofp = ++cp;
	      while(*cp!='"' && *cp!='\n') cp++;
	      *cp++ = '\0';
	      break;
	    case '\\':
	      eofp = ++cp;
	      while(*cp!=' ' && *cp!='\t' && *cp!='\n') cp++;
	      *cp++ = '\0';
	      break;
	    default:
	      eofp = cp++;
	      while(*cp!=' ' && *cp!='\t' && *cp!='\n') cp++;
	      *cp++ = '\0';
	      break;
	  }
	} else {
	  switch(*cp) {
	    case '\n':
	      return(1);
	    case '\'':
	      cpb = ++cp;
	      while(*cp!='\'' && *cp!='\n') cp++;
	      *cp++ = '\0';
	      break;
	    case '"':
	      cpb = ++cp;
	      while(*cp!='"' && *cp!='\n') cp++;
	      *cp++ = '\0';
	      break;
	    default:
	      cpb = cp++;
	      while(*cp!=' ' && *cp!='\t' && *cp!='\n') cp++;
	      *cp++ = '\0';
	      break;
	  }
	  if(*cpb) {
	    if((infile = fopen(cpb, "r")) == NULL) {
	      fprintf(stderr, "Can't open %s for redirected stdin\n", cpb);
	      exit(1);
	    }
	  }
	}
	break;
      case '>':
        if(*++cp=='>') { mode="a"; cp++; } else mode="w";
        while(*cp==' ' || *cp=='\t') cp++;
        switch(*cp) {
	  case '\n':
	    return(1);
	  case '\'':
	    cpb = ++cp;
	    while(*cp!='\'' && *cp!='\n') cp++;
	    *cp++ = '\0';
	    break;
	  case '"':
	    cpb = ++cp;
	    while(*cp!='"' && *cp!='\n') cp++;
	    *cp++ = '\0';
	    break;
	  default:
	    cpb = cp++;
	    while(*cp!=' ' && *cp!='\t' && *cp!='\n') cp++;
	    *cp++ = '\0';
	    break;
	}
	if(cond && *cpb) {
	  if((outfile = fopen(cpb, mode))==NULL) {
	    fprintf(stderr, "Could not open %s for output redirection\n", cpb);
	    exit(1);
	  }
	}
	break;
      default:
        clargv[clargc++] = cp++;
	while(*cp!=' ' && *cp!='\t' && *cp!='\n') cp++;
	*cp++ = '\0';
	break;
    }
  } while(clargc < MAXARG);
  return(1);
}

main(argc, argv)
int argc;
char **argv;
{
  if(argc==2) {
    if(freopen(argv[1], "r", stdin) == NULL) {
      fprintf(stderr, "Open of %s failed\n", argv[1]);
      exit(1);
    }
  } else if(argc!=1) {
    fprintf(stderr, "to many arguments\n");
    exit(1);
  }
  /* skip header */
  if(!nextline()) {
    fprintf(stderr, "empty file\n");
    exit(1);
  }
  while(line[0] != '#' && line[0] != ':') {
    fprintf(stderr, "skipping header: %s", line);
    if(!nextline()) {
      fprintf(stderr, "No commands found, perhaps no comments??\n");
      exit(1);
    }
  }
  while(clparse()) {
    if(clargc > 0) {
      fprintf(stderr, "Command: %s\n", clargv[0]);
           if(strEQ(clargv[0], "if"))	if_();
      else if(strEQ(clargv[0], "else")) {if(cl>0 && condl[cl-1]) cond ^= TRUE;}
      else if(strEQ(clargv[0], "fi"))	{if(cl>0) cond = condl[--cl];}
      else if(!cond) 			skipin();
      else if(strEQ(clargv[0], "cat"))	cat();
      else if(strEQ(clargv[0], "exit")) break;
      else if(strEQ(clargv[0], "echo")) echo();
      else if(strEQ(clargv[0], "sed"))	sed();
      else if(strEQ(clargv[0], "mkdir")) mkdir();
      else if(strEQ(clargv[0], "cd"))	cd();
      else if(strEQ(clargv[0], "export"))
      		fprintf(stderr, "Ignoring export\n");
      else if(strEQ(clargv[0], "rm"))	rm();
      else {
        fprintf(stderr, "Unknown command: %s\n", clargv[0]); 
        exit(1);
      }
    }
  }
}

echo() {
  char **arg = &clargv[1];
  while(--clargc > 0) {
    fputs(*arg++, outfile);
    if(clargc > 1) putc(' ', outfile);
  }
  putc('\n', outfile);
}

cat()
{
  FILE *oldin;
  char **arg = &clargv[1];
  if(clargc > 1) {
    oldin = infile;
    while(--clargc > 0) {
      if(infile!=stdin && infile!=oldin) {
        fclose(infile);
	infile = stdin;
      }
      if(strEQ(*arg, "-")) {
        infile = oldin;
	arg++;
      } else infile = fopen(*arg++, "r");
      if(infile!=NULL) {
        while(nextline()) {
          fputs(line, outfile);
        }
      } else {
        if(!strEQ(arg[-1], "/dev/null")) {
          fprintf(stderr, "Could not open %s to cat\n", arg[-1]);
	  exit(1);
	}
      }
    }
    if(infile!=stdin && infile!=oldin)
      fclose(infile);
    infile = oldin;
  } else {
fprintf(stderr, "Cat up to %s\n", eofp);
    while(nextline()) {
      fputs(line, outfile);
    }
  }
}

sed() {
  register char *cp;
  register char *cpb;
  register char *cps;
  register char sep;
  switch(clargc) {
    case 1:
      fprintf(stderr, "No sed commands\n");
      exit(1);
    case 2:
      cp = clargv[1];
      break;
    case 3:
      if(!strEQ(clargv[1], "-e")) {
        fprintf(stderr, "To fancy for fake sed\n");
	exit(1);
      }
      cp = clargv[2];
      break;
    default:
      fprintf(stderr, "To many arguments for fake sed\n");
      exit(1);
  }
  if(*cp++!='s') {
    fprintf(stderr, "Unknown command to fake sed\n");
    exit(1);
  }
  sep = *cp++;
  cpb = cp;
  while(*cp!=sep && *cp) cp++;
  if(*cp) *cp++='\0';
  if(*cp!=sep && *cp) {
    fprintf(stderr, "Replacement strings not yet handled by fake sed\n");
    exit(1);
  }
  while(nextline()) {
    cp = cpb;
    cps = &line[0];
    while(*cp) {
      switch(sep = *cp++) {
        case '[':
        case '\\':
          fprintf(stderr, "Regular expression to fancy for fake sed\n");
	  exit(1);
        case '.':
          if(*cps) cps++;
	  break;
        default:
          if(*cps==sep) cps++;
	  else {
	    fputs(line, outfile);
	    cp = "";
	    continue;
	  }
	  break;
      }
      if(!*cp) {
        fputs(cps, outfile);
	continue;
      }
    }
  }
}

mkdir() {
  if(clargc!=2) {
    fprintf(stderr, "Wrong number of aguments to fake mkdir\n");
    exit(1);
  }
#ifdef OSK
  if(mknod(clargv[1], S_IFDIR | S_IREAD | S_IWRITE)) {
    fprintf(stderr, "fake mkdir failed to create %s\n", clargv[1]);
    exit(1);
  }
#else
  insert your directory creation code here
#endif
}

cd() {
  if(clargc!=2) {
    fprintf(stderr, "Wrong number of arguments to fake cd\n");
    exit(1);
  }
  if(chdir(clargv[1])) {
    fprintf(stderr, "Fake cd failed to %s\n", clargv[1]);
    exit(1);
  }
}

skipin() {
  if(infile!=stdin || eofp==NULL) return;
  while(nextline()) {}
}

if_() {
  int invert = 0;
  register char **arg = &clargv[1];
  int pd;
  if(!(condl[cl++] = cond)) return;
  if(clargc<3) {
    fprintf(stderr, "To few arguments to if\n");
    exit(1);
  }
  if(!strEQ(*arg++, "test")) {
    fprintf(stderr, "Unsupported if contdition: %s\n", clargv[1]);
    exit(1);
  }
  if(strEQ(*arg, "!")) {
    invert = 1;
    arg++;
    clargc--;
  }
  if(clargc != 4) {
    fprintf(stderr, "Wrong number of arguments to if test\n");
    exit(1);
  }
  if(*(*arg)++ != '-' || (*arg)[1] != '\0') {
    fprintf(stderr, "Unknown option in test: %s\n", --*arg);
    exit(1);
  }
  switch(**arg) {
#ifdef	OSK
    case 'd':
      cond = (access(*++arg, S_IFDIR)==0) ^ invert;
      break;
    case 'f':
      cond = (access(*++arg, 0)==0) ^ invert;
      break;
    case 's':
      if(pd = open(*++arg, S_IREAD)) {
        cond = (_gs_size(pd) > 0) ^ invert;
	close(pd);
      } else cond = invert;
      break;
#else
  insert your test code here
#endif
    default:
      fprintf(stderr, "Unknown test in if: -%c\n", **arg);
      exit(1);
  }
  clparse();
  if(clargc!=1 || !strEQ(clargv[0], "then")) {
    fprintf(stderr, "if is missing a then\n");
    exit(1);
  }
}

rm() {
  register char **arg = &clargv[1];
  while(--clargc > 0) {
    if(unlink(*(arg++))) fprintf(stderr, "Could not delete: %s\n", arg[-1]);
  }
}

 
-------------------------------------
The views expressed in OS-9 Discussions are those of the individual authors
only.
------
Moderator:  John Daleske   cbosgd!cbdkc1!daleske    daleske@cbdkc1.ATT.COM

Submissions should go to   cbosgd!os9               os9@cbosgd.ATT.COM
Comments to the moderator
 or to join the mailing    cbosgd!os9-request       os9-request@cbosgd.ATT.COM
 list.

*********************
End of OS-9 Discussions
*********************