void interpret(s_line line) { if (!strcmp(line.command, "PING")) pong(line.params[0]); flushline(line); }
/* * error output function * * param: string ptr to message. Null ptr or empty string = no message * * usage: same as printf(). */ void syntax_error(char *msg) { char tmp[200]; int ret; if (msg!=NULL && *msg) { error_counter++; sprintf(tmp,"[3][ERROR Line %ld:|%s][Cont|Stop]", cline, msg ); ret = form_alert(1,tmp); if (ret==2) /* STOP: */ { /* quick run through file */ do { flushline(); } while (sym!=EOS); } } }
EXTRADECLS #endif /***************************************************************************** * * * This is a program which illustrates the use of nauty. * * Commands are read from stdin, and may be separated by white space, * * commas or not separated. Output is written to stdout. * * For a short description, see the nauty User's Guide. * * * *****************************************************************************/ main() { int m,n,newm,newn; boolean gvalid,ovalid,cvalid,pvalid,minus,prompt,doquot; int i,worksize,numcells,refcode,umask,qinvar; int oldorg; char *s1,*s2,*invarprocname; int c,d; register long li; set *gp; double timebefore,timeafter; char filename[100]; graph *savedg; nvector *savedlab; int sgn,sgactn,sgorg; int cgactn,gactn; curfile = 0; fileptr[curfile] = stdin; prompt = DOPROMPT(INFILE); outfile = stdout; n = m = 1; #ifdef INITSEED INITSEED; #endif umask = 0; pvalid = FALSE; gvalid = FALSE; ovalid = FALSE; cvalid = FALSE; minus = FALSE; worksize = 2*MAXM*WORKSIZE; labelorg = oldorg = 0; cgactn = sgactn = gactn = 0; #ifdef DYNALLOC workspace = (setword*) ALLOCS(WORKSIZE,2*MAXM*sizeof(setword)); ptn = (nvector*) ALLOCS(MAXN,sizeof(nvector)); orbits = (nvector*) ALLOCS(MAXN,sizeof(nvector)); perm = (permutation*) ALLOCS(MAXN,sizeof(permutation)); if (workspace == NILSET || ptn == (nvector*)NULL || orbits == (nvector*)NULL || perm == (permutation*)NULL) { fprintf(ERRFILE,"ALLOCS failed; reduce MAXN.\n\n"); EXIT; } #endif #ifdef INITIALIZE INITIALIZE; #endif allocg(&g,&lab,&gactn,n); if (gactn == 0) { fprintf(ERRFILE,"ALLOCS failed for g: this shouldn't happen.\n\n"); EXIT; } invarprocname = "none"; if (prompt) { fprintf(PROMPTFILE,"Dreadnaut version %s.\n",DREADVERSION); fprintf(PROMPTFILE,"> "); } /* Calling dummy routines in nautinv.c, nauty.c and nautil.c causes those segments to get loaded in various Macintosh variants. This causes an apparent, but illusory, improvement in the time required for the first call to nauty(). */ nautinv_null(); nautil_null(); nauty_null(); while (curfile >= 0) if ((c = getc(INFILE)) == EOF || c == '\004') { fclose(INFILE); --curfile; if (curfile >= 0) prompt = DOPROMPT(INFILE); } else switch (c) { case '\n': /* possibly issue prompt */ if (prompt) fprintf(PROMPTFILE,"> "); minus = FALSE; break; case ' ': /* do nothing */ case '\t': #ifndef NLMAP case '\r': #endif case '\f': break; case '-': /* remember this for next time */ minus = TRUE; break; case '+': /* forget - */ case ',': case ';': minus = FALSE; break; case '<': /* new input file */ minus = FALSE; if (curfile == MAXIFILES - 1) fprintf(ERRFILE,"exceeded maximum input nesting of %d\n\n", MAXIFILES); if (!readstring(INFILE,filename)) { fprintf(ERRFILE, "missing file name on '>' command : ignored\n\n"); break; } if ((fileptr[curfile+1] = fopen(filename,"r")) == NULL) { for (s1 = filename; *s1 != '\0'; ++s1) {} for (s2 = def_ext; (*s1 = *s2) != '\0'; ++s1, ++s2) {} fileptr[curfile+1] = fopen(filename,"r"); } if (fileptr[curfile+1] != NULL) { ++curfile; prompt = DOPROMPT(INFILE); if (prompt) fprintf(PROMPTFILE,"> "); } else fprintf(ERRFILE,"can't open input file\n\n"); break; case '>': /* new output file */ if ((d = getc(INFILE)) != '>') ungetc((char)d,INFILE); if (minus) { minus = FALSE; if (outfile != stdout) { fclose(outfile); outfile = stdout; } } else { if (!readstring(INFILE,filename)) { fprintf(ERRFILE, "improper file name, reverting to stdout\n\n"); outfile = stdout; break; } OPENOUT(outfile,filename,d=='>'); if (outfile == NULL) { fprintf(ERRFILE, "can't open output file, reverting to stdout\n\n"); outfile = stdout; } } break; case '!': /* ignore rest of line */ do c = getc(INFILE); while (c != '\n' && c != EOF); if (c == '\n') ungetc('\n',INFILE); break; case 'n': /* read n value */ minus = FALSE; i = getint(INFILE); if (i <= 0 || i > MAXN) fprintf(ERRFILE, " n can't be less than 1 or more than %d\n\n",MAXN); else { gvalid = FALSE; ovalid = FALSE; cvalid = FALSE; pvalid = FALSE; n = i; m = (n + WORDSIZE - 1) / WORDSIZE; allocg(&g,&lab,&gactn,n); if (gactn == 0) { fprintf(ERRFILE,"can't allocate space for graph\n"); n = m = 1; break; } } break; case 'g': /* read graph */ minus = FALSE; readgraph(INFILE,g,options.digraph,prompt,FALSE, options.linelength,m,n); gvalid = TRUE; cvalid = FALSE; ovalid = FALSE; break; case 'e': /* edit graph */ minus = FALSE; readgraph(INFILE,g,options.digraph,prompt,gvalid, options.linelength,m,n); gvalid = TRUE; cvalid = FALSE; ovalid = FALSE; break; case 'r': /* relabel graph and current partition */ minus = FALSE; if (gvalid) { allocg(&canong,(nvector**)NULL,&cgactn,n); if (cgactn == 0) { fprintf(ERRFILE, "can't allocate work space for 'r'\n\n"); break; } readperm(INFILE,perm,prompt,n); relabel(g,(pvalid ? lab : (nvector*)NULL),perm,canong,m,n); cvalid = FALSE; ovalid = FALSE; } else fprintf(ERRFILE,"g is not defined\n\n"); break; case '_': /* complement graph */ minus = FALSE; if (gvalid) { complement(g,m,n); cvalid = FALSE; ovalid = FALSE; } else fprintf(ERRFILE,"g is not defined\n\n"); break; case '@': /* copy canong into savedg */ minus = FALSE; if (cvalid) { allocg(&savedg,&savedlab,&sgactn,n); if (sgactn == 0) { fprintf(ERRFILE,"can`t allocate space for h'\n\n"); break; } sgn = n; for (li = (long)n * (long)m; --li >= 0;) savedg[li] = canong[li]; for (i = n; --i >= 0;) savedlab[i] = lab[i]; sgorg = labelorg; } else fprintf(ERRFILE,"h is not defined\n\n"); break; case '#': /* compare canong to savedg */ if ((d = getc(INFILE)) != '#') ungetc((char)d,INFILE); if (cvalid) { if (sgactn > 0) { if (sgn != n) fprintf(OUTFILE, "h and h' have different sizes.\n"); else { for (li = (long)n * (long)m; --li >= 0;) if (savedg[li] != canong[li]) break; if (li >= 0) fprintf(OUTFILE, "h and h' are different.\n"); else { fprintf(OUTFILE, "h and h' are identical.\n"); if (d == '#') putmapping(OUTFILE,savedlab,sgorg, lab,labelorg,options.linelength,n); } } } else fprintf(ERRFILE,"h' is not defined\n\n"); } else fprintf(ERRFILE,"h is not defined\n\n"); break; case 'j': /* relabel graph randomly */ minus = FALSE; if (gvalid) { allocg(&canong,(nvector**)NULL,&cgactn,n); if (cgactn == 0) { fprintf(ERRFILE, "can't allocate work space for 'j'\n\n"); break; } ranperm(perm,n); relabel(g,(pvalid ? lab : (nvector*)NULL),perm,canong,m,n); cvalid = FALSE; ovalid = FALSE; } else fprintf(ERRFILE,"g is not defined\n\n"); break; case 'v': /* write vertex degrees */ minus = FALSE; if (gvalid) putdegs(OUTFILE,g,options.linelength,m,n); else fprintf(ERRFILE,"g is not defined\n\n"); break; case '%': /* do Mathon doubling operation */ minus = FALSE; if (gvalid) { if (2L * ((long)n + 1L) > MAXN) { fprintf(ERRFILE,"n can't be more than %d\n\n",MAXN); break; } newn = 2 * (n + 1); newm = (newn + WORDSIZE - 1) / WORDSIZE; allocg(&canong,(nvector**)NULL,&cgactn,n); if (cgactn == 0) { fprintf(ERRFILE, "can't allocate work space for '%'\n\n"); break; } for (li = (long)n * (long)m; --li >= 0;) canong[li] = g[li]; allocg(&g,&lab,&gactn,newn); if (gactn == 0) { fprintf(ERRFILE,"can't allocate space for graph \n\n"); break; } mathon(canong,m,n,g,newm,newn); m = newm; n = newn; cvalid = FALSE; ovalid = FALSE; pvalid = FALSE; } else fprintf(ERRFILE,"g is not defined\n\n"); break; case 's': /* generate random graph */ minus = FALSE; i = getint(INFILE); if (i <= 0) i = 2; rangraph(g,options.digraph,i,m,n); gvalid = TRUE; cvalid = FALSE; ovalid = FALSE; break; case 'q': /* quit */ EXIT; break; case '"': /* copy comment to output */ minus = FALSE; copycomment(INFILE,OUTFILE,'"'); break; case 'I': /* do refinement and invariants procedure */ if (!pvalid) unitptn(lab,ptn,&numcells,n); cellstarts(ptn,0,active,m,n); #ifdef CPUTIME timebefore = CPUTIME; #endif doref(g,lab,ptn,0,&numcells,&qinvar,perm,active,&refcode, refine,options.invarproc, 0,0,options.invararg,options.digraph,m,n); #ifdef CPUTIME timeafter = CPUTIME; #endif fprintf(OUTFILE," %d cell%s; code = %x", SS(numcells,"","s"),refcode); if (options.invarproc != NILFUNCTION) fprintf(OUTFILE," (%s %s)",invarprocname, (qinvar == 2 ? "worked" : "failed")); #ifdef CPUTIME fprintf(OUTFILE,"; cpu time = %.2f seconds\n", timeafter-timebefore); #else fprintf(OUTFILE,"\n"); #endif if (numcells > 1) pvalid = TRUE; break; case 'i': /* do refinement */ if (!pvalid) unitptn(lab,ptn,&numcells,n); cellstarts(ptn,0,active,m,n); if (m == 1) refine1(g,lab,ptn,0,&numcells,perm,active,&refcode,m,n); else refine(g,lab,ptn,0,&numcells,perm,active,&refcode,m,n); fprintf(OUTFILE," %d cell%s; code = %x\n", SS(numcells,"","s"),refcode); if (numcells > 1) pvalid = TRUE; break; case 'x': /* execute nauty */ minus = FALSE; ovalid = FALSE; cvalid = FALSE; if (!gvalid) { fprintf(ERRFILE,"g is not defined\n\n"); break; } if (pvalid) { fprintf(OUTFILE,"[fixing partition]\n"); options.defaultptn = FALSE; } else options.defaultptn = TRUE; options.outfile = outfile; if (options.getcanon) { allocg(&canong,(nvector**)NULL,&cgactn,n); if (cgactn == 0) { fprintf(ERRFILE,"can't allocate space for h\n\n"); break; } } firstpath = TRUE; #ifdef CPUTIME timebefore = CPUTIME; #endif nauty(g,lab,ptn,NILSET,orbits,&options,&stats,workspace, worksize,m,n,canong); #ifdef CPUTIME timeafter = CPUTIME; #endif if (stats.errstatus != 0) fprintf(ERRFILE, "nauty returned error status %d [this can't happen]\n\n", stats.errstatus); else { if (options.getcanon) cvalid = TRUE; ovalid = TRUE; fprintf(OUTFILE,"%d orbit%s",SS(stats.numorbits,"","s")); if (stats.grpsize2 == 0) fprintf(OUTFILE,"; grpsize=%.0f",stats.grpsize1+0.1); else { while (stats.grpsize1 >= 10.0) { stats.grpsize1 /= 10.0; ++stats.grpsize2; } fprintf(OUTFILE,"; grpsize=%12.10fe%d", stats.grpsize1,stats.grpsize2); } fprintf(OUTFILE,"; %d gen%s", SS(stats.numgenerators,"","s")); fprintf(OUTFILE,"; %ld node%s",SS(stats.numnodes,"","s")); if (stats.numbadleaves) fprintf(OUTFILE," (%ld bad lea%s)", SS(stats.numbadleaves,"f","ves")); fprintf(OUTFILE,"; maxlev=%d\n", stats.maxlevel); fprintf(OUTFILE,"tctotal=%ld",stats.tctotal); if (options.getcanon) fprintf(OUTFILE,"; canupdates=%ld",stats.canupdates); #ifdef CPUTIME fprintf(OUTFILE,"; cpu time = %.2f seconds\n", timeafter-timebefore); #else fprintf(OUTFILE,"\n"); #endif if (options.invarproc != NILFUNCTION && options.maxinvarlevel != 0) { fprintf(OUTFILE,"invarproc \"%s\" succeeded %ld/%ld", invarprocname,stats.invsuccesses,stats.invapplics); if (stats.invarsuclevel > 0) fprintf(OUTFILE," beginning at level %d.\n", stats.invarsuclevel); else fprintf(OUTFILE,".\n"); } } break; case 'f': /* read initial partition */ if (minus) { pvalid = FALSE; minus = FALSE; } else { readptn(INFILE,lab,ptn,&numcells,prompt,n); pvalid = TRUE; } break; case 't': /* type graph */ minus = FALSE; if (!gvalid) fprintf(ERRFILE,"g is not defined\n\n"); else putgraph(OUTFILE,g,options.linelength,m,n); break; case 'T': /* type graph preceded by n, $ and g commands */ minus = FALSE; if (!gvalid) fprintf(ERRFILE,"g is not defined\n\n"); else { fprintf(OUTFILE,"n=%d $=%d g\n",n,labelorg); putgraph(OUTFILE,g,options.linelength,m,n); fprintf(OUTFILE,"$$\n"); } break; case 'u': /* call user procs */ if (minus) { umask = 0; minus = FALSE; } else { umask = getint(INFILE); if (umask < 0) umask = ~0; } if (umask & U_NODE) options.usernodeproc = NODEPROC; else options.usernodeproc = NILFUNCTION; if (umask & U_AUTOM) options.userautomproc = AUTOMPROC; else options.userautomproc = NILFUNCTION; if (umask & U_LEVEL) options.userlevelproc = LEVELPROC; else options.userlevelproc = NILFUNCTION; if (umask & U_TCELL) options.usertcellproc = TCELLPROC; else options.usertcellproc = NILFUNCTION; if (umask & U_REF) options.userrefproc = REFPROC; else options.userrefproc = NILFUNCTION; break; case 'o': /* type orbits */ minus = FALSE; if (ovalid) putorbits(OUTFILE,orbits,options.linelength,n); else fprintf(ERRFILE,"orbits are not defined\n\n"); break; case 'b': /* type canonlab and canong */ minus = FALSE; if (cvalid) putcanon(OUTFILE,lab,canong,options.linelength,m,n); else fprintf(ERRFILE,"h is not defined\n\n"); break; case 'z': /* type hashcode for canong */ minus = FALSE; if (cvalid) fprintf(OUTFILE,"[%8lx %8lx]\n", hash(canong,(long)m * (long)n,13), hash(canong,(long)m * (long)n,7)); else fprintf(ERRFILE,"h is not defined\n\n"); break; case 'c': /* set getcanon option */ options.getcanon = !minus; minus = FALSE; break; case 'w': /* read size of workspace */ minus = FALSE; worksize = getint(INFILE); if (worksize > 2*MAXM*WORKSIZE) { fprintf(ERRFILE, "too big - setting worksize = %d\n\n", 2*MAXM*WORKSIZE); worksize = 2*MAXM*WORKSIZE; } break; case 'l': /* read linelength for output */ options.linelength = getint(INFILE); minus = FALSE; break; case 'y': /* set tc_level field of options */ options.tc_level = getint(INFILE); minus = FALSE; break; case 'k': /* set invarlev fields of options */ options.mininvarlevel = getint(INFILE); options.maxinvarlevel = getint(INFILE); minus = FALSE; break; case 'K': /* set invararg field of options */ options.invararg = getint(INFILE); minus = FALSE; break; case '*': /* set invarproc field of options */ minus = FALSE; d = getint(INFILE); if (d >= -1 && d <= NUMINVARS-2) { options.invarproc = invarproc[d+1].entrypoint; invarprocname = invarproc[d+1].name; } else fprintf(ERRFILE,"no such vertex-invariant\n\n"); break; case 'a': /* set writeautoms option */ options.writeautoms = !minus; minus = FALSE; break; case 'm': /* set writemarkers option */ options.writemarkers = !minus; minus = FALSE; break; case 'p': /* set cartesian option */ options.cartesian = !minus; minus = FALSE; break; case 'd': /* set digraph option */ if (options.digraph && minus) gvalid = FALSE; options.digraph = !minus; minus = FALSE; break; case '$': /* set label origin */ if ((d = getc(INFILE)) == '$') labelorg = oldorg; else { ungetc((char)d,INFILE); oldorg = labelorg; i = getint(INFILE); if (i < 0) fprintf(ERRFILE,"labelorg must be >= 0\n\n"); else labelorg = i; } break; case '?': /* type options, etc. */ minus = FALSE; fprintf(OUTFILE,"m=%d n=%d labelorg=%d",m,n,labelorg); if (!gvalid) fprintf(OUTFILE," g=undef"); else { li = 0; for (i = 0, gp = g; i < n; ++i, gp += m) li += setsize(gp,m); if (options.digraph) fprintf(OUTFILE," arcs=%ld",li); else fprintf(OUTFILE," edges=%ld",li/2); } fprintf(OUTFILE," options=(%cc%ca%cm%cp%cd", PM(options.getcanon),PM(options.writeautoms), PM(options.writemarkers),PM(options.cartesian), PM(options.digraph)); if (umask & 31) fprintf(OUTFILE," u=%d",umask&31); if (options.tc_level > 0) fprintf(OUTFILE," y=%d",options.tc_level); if (options.mininvarlevel != 0 || options.maxinvarlevel != 0) fprintf(OUTFILE," k=(%d,%d)", options.mininvarlevel,options.maxinvarlevel); if (options.invararg > 0) fprintf(OUTFILE," K=%d",options.invararg); fprintf(OUTFILE,")\n"); fprintf(OUTFILE,"linelen=%d worksize=%d input_depth=%d", options.linelength,worksize,curfile); if (options.invarproc != NILFUNCTION) fprintf(OUTFILE," invarproc=%s",invarprocname); if (pvalid) fprintf(OUTFILE,"; %d cell%s",SS(numcells,"","s")); else fprintf(OUTFILE,"; 1 cell"); fprintf(OUTFILE,"\n"); if (OUTFILE != PROMPTFILE) fprintf(PROMPTFILE,"m=%d n=%d depth=%d labelorg=%d\n", m,n,curfile,labelorg); break; case '&': /* list the partition and possibly the quotient */ if ((d = getc(INFILE)) == '&') doquot = TRUE; else { ungetc((char)d,INFILE); doquot = FALSE; } minus = FALSE; if (pvalid) putptn(OUTFILE,lab,ptn,0,options.linelength,n); else fprintf(OUTFILE,"unit partition\n"); if (doquot) { if (!pvalid) unitptn(lab,ptn,&numcells,n); putquotient(OUTFILE,g,lab,ptn,0,options.linelength,m,n); } break; case 'h': /* type help information */ minus = FALSE; help(PROMPTFILE); break; default: /* illegal command */ fprintf(ERRFILE,"'%c' is illegal - type 'h' for help\n\n",c); flushline(INFILE); if (prompt) fprintf(PROMPTFILE,"> "); break; } /* end of switch */ }
/* * newline() breaks the current line, even if there's nothing to be * broken on it. */ void newline() { if (!flushline()) addnewline(); } /* newline */
/* * breakline() breaks the current line, if there's anything to be broken */ void breakline() { flushline(); } /* breakline */
static void drop (void) { flushline(false); }
/* plain line handling */ static void print (void) { flushline(true); }
/* * interprete_composetabentry() * read a single compose table entry. * Format is "{" 3_bytes_of_data [ , flags ] "}" * * Param: none * Return: compose sequence longword if syntax was correct. * * Global: next symbol is read. * */ unsigned long interprete_composetabentry(void) { char *p; int nbyte, flags; union { char entry[4]; long Long; } retval; flags=0; nbyte=0; retval.Long=0L; getsym(); if (sym==S_LBRACE) { /* read entry data */ do { getsym(); switch (sym) { case INTEGERCONST: if (nbyte<3) retval.entry[nbyte] = (unsigned char)atoi(symbol.name); nbyte++; break; case HEXCONST: if (nbyte<3) retval.entry[nbyte] = (unsigned char)strtol(symbol.name,NULL,16); nbyte++; break; case BINCONST: if (nbyte<3) retval.entry[nbyte] = (unsigned char)strtol(symbol.name,NULL,2); nbyte++; break; case STRINGCONST: p = symbol.name; while (*p && nbyte<3) retval.entry[nbyte++] = *p++; while (*p++) nbyte++; break; /* Flag to enable AUTOMULTI mode for this sequence */ case K_AUTOMULTI: flags |= CKB_AUTOMULTI; break; case K_NOAUTOMULTI: flags &= ~CKB_AUTOMULTI; break; case K_ORDER: flags |= CKB_ORDER; break; case K_NOORDER: flags &= ~CKB_ORDER; break; default: if (nbyte<3) syntax_error("Bad data type, constant expected"); else syntax_error("Bad data type, FLAG word expected"); goto skipread; /* break; */ } getsym(); skipread:; } while (sym==S_COMMA); /* expect } to close an entry */ if (sym==S_RBRACE) { if (nbyte<3) syntax_error("Compose sequence <3 chars"); else if (nbyte>3) syntax_error("Compose sequence >3 chars"); retval.entry[3] = flags; getsym(); } else { syntax_error("closing brace '}' expected"); flushline(); } } else if (sym==S_COMMA) { syntax_error("opening brace '{' expected"); } return retval.Long; }
/* * interprete_switches() * Reads the various switch options. * switches are specified on one single line. * * Param: none * Return: none * * Prerequisites: * Parser must be in the switch section of the file. * Global: next symbol is already read. (due to lookahead) * */ void interprete_switches(void) { int i = 0; char *p; char *e_parameter = "Bad or missing switch option"; do { getsym(); switch (sym) { case NEWLINE: /* empty line... */ break; case K_COMPOSE: do { getsym(); /* read next sym (should be a parameter) */ if (sym==K_ON) ckb.switches.compose |= CKB_ON; else if (sym==K_OFF) ckb.switches.compose &= ~CKB_ON; else if (sym==K_DEC_MODE) ckb.switches.compose &= ~(CKB_MULTICHAR|CKB_IMPLICIT); else if (sym==K_MULTICHAR) { ckb.switches.compose |= CKB_MULTICHAR; ckb.switches.compose &= ~CKB_IMPLICIT; } else if (sym==K_AUTOMULTI) ckb.switches.compose |= (CKB_MULTICHAR|CKB_IMPLICIT); else if (sym==K_ORDER) ckb.switches.compose |= CKB_ORDERSENSITIVE; else if (sym==K_NOORDER) ckb.switches.compose &= ~CKB_ORDERSENSITIVE; else { syntax_error(e_parameter); flushline(); break; /* leave parsing loop */ }; getsym(); /* optional comma indicates that another switch option follows */ } while (sym==S_COMMA); /* symbol other than a comma read */ break; case K_DEADKEY: i=0; do { getsym(); if (sym==K_ON) ckb.switches.deadkey |= CKB_ON; else if (sym==K_OFF) ckb.switches.deadkey &= ~CKB_ON; else if (sym==INTEGERCONST) { if (i<MAX_DEADKEYS) ckb.deadkeys[i++]=(unsigned char)atoi(symbol.name); } else if (sym==BINCONST) { if (i<MAX_DEADKEYS) ckb.deadkeys[i++]=(unsigned char)strtol(symbol.name, NULL, 2); } else if (sym==HEXCONST) { if (i<MAX_DEADKEYS) ckb.deadkeys[i++]=(unsigned char)strtol(symbol.name, NULL, 16); } else if (sym==STRINGCONST) { p=symbol.name; while (*p && i<MAX_DEADKEYS) ckb.deadkeys[i++]=*p++; ckb.deadkeys[i]=NUL; } getsym(); /* read next symbol */ } while (sym==S_COMMA); break; case K_EXTKEY: getsym(); if (sym==K_ON) ckb.switches.extkey |= CKB_ON; else if (sym==K_OFF) ckb.switches.extkey &= ~CKB_ON; else syntax_error(e_parameter); getsym(); /* read next symbol */ break; case K_ALT_NNN: getsym(); if (sym==K_ON) ckb.switches.alt_nnn |= CKB_ON; else if (sym==K_OFF) ckb.switches.alt_nnn &= ~CKB_ON; else syntax_error(e_parameter); getsym(); /* read next symbol */ break; case K_TABLE_APPLIES_TO: do { getsym(); if (sym==K_NOTHING) ckb.switches.tablevalid = CKB_NONE; else if (sym==K_KEYBOARD) ckb.switches.tablevalid |= CKB_KEYBOARD; else if (sym==K_COMPOSE) ckb.switches.tablevalid |= CKB_COMPOSE; else if (sym==K_BOTH) ckb.switches.tablevalid = CKB_KEYBOARD|CKB_COMPOSE; else { syntax_error(e_parameter); break; }; getsym(); } while (sym==S_COMMA); break; }; } while (sym==NEWLINE); }
/* * interprete_file() * interpreter entry point. * * No symbols have been read yet. */ void interprete_file(void) { char tmp[100]; int go_ahead = TRUE; clear_ckbtable(); error_counter = 0; /* global errorcounter */ getsym(); /* read the first symbol */ do { switch (sym) { case NEWLINE: getsym(); /* newline: empty line, read next sym */ case EOS: break; /* no further action, loop aborts */ case K_NAME: /* define the table name */ getsym(); if (sym==STRINGCONST) { if (strlen(symbol.name)>MAXTABLENAMELENGTH) syntax_error("Table name too long, truncating"); strncpy(ckb.tabname,symbol.name,MAXTABLENAMELENGTH); ckb.tabname[MAXTABLENAMELENGTH]=NUL; } else syntax_error("Table name expected"); getsym(); break; case K_SWITCHES: /* define the switches */ interprete_switches(); break; case K_KBTAB_NORMAL: /* load the kbd tables */ interprete_kbtab(0); break; case K_KBTAB_SHIFT: interprete_kbtab(1); break; case K_KBTAB_CAPSLOCK: interprete_kbtab(2); break; case K_KBTAB_COMPOSE: /* load the compose table */ interprete_composetab(); break; case K_END: /* accept file */ getsym(); /* read next sym (NEWLINE) */ /* check_ckbtable(); */ go_ahead = FALSE; break; default: sprintf(tmp, "Unexpected symbol:|(%s)", symbol.name); syntax_error(tmp); /* syntax_error("Unexpected symbol"); */ flushline(); break; }; } while (go_ahead && sym!=EOS); if (go_ahead) syntax_error("END statement missing"); }
/* * Special get_symbol: * */ void getsym(void) { get_symbol(); if (sym==S_SEMICOLON) flushline(); /* ignore comments */ }
/* handle escape characters, writing to output */ void cook_buf(struct ios_ops *ios, unsigned char *buf, int num) { int current = 0; if (in_escape) { /* cook_buf last called with an incomplete escape sequence */ switch (help_state) { case 0: help_send_escape(ios, buf[0]); break; case 1: help_set_terminal(ios, buf[0]); break; default: help_set_speed(ios, buf[0]); } num--; /* advance to the next character in the buffer */ buf++; } while (current < num) { /* big while loop, to process all the charactes in buffer */ /* look for the next escape character '~' */ while ((current < num) && (buf[current] != 28)) current++; /* and write the sequence befor esc char to the comm port */ if (current) { if (in_echo) { write(STDOUT_FILENO, buf, current); /* echo */ } if (!in_line) write(ios->fd, buf, current); else writeline(ios->fd, buf, current); } if (current < num) { /* process an escape sequence */ /* flush buffers */ fflush(stdout); if (in_line) flushline(ios->fd); /* found an escape character */ if (help_state == 0) help_escape(); current++; if (current >= num) { /* interpret first character of next sequence */ in_escape = 1; return; } switch (help_state) { case 0: help_send_escape(ios, buf[current]); break; case 1: help_set_terminal(ios, buf[current]); break; default: help_set_speed(ios, buf[current]); } /* end switch */ current++; if (current >= num) return; } /* if - end of processing escape sequence */ num -= current; buf += current; current = 0; } /* while - end of processing all the charactes in the buffer */ return; }
void plD_eop_imp(PLStream *pls) { flushline(pls); fprintf(pls->OutFile, "%c", ENDPAGE); }