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 *********************