132471Sbostic /* 232471Sbostic * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved. 332471Sbostic * 432471Sbostic * Copy permission is hereby granted provided that this notice is 532471Sbostic * retained on all partial or complete copies. 632471Sbostic * 732471Sbostic * For more info on this and all of my stuff, mail edjames@berkeley.edu. 832471Sbostic */ 932471Sbostic 1032471Sbostic #ifndef lint 11*32472Sbostic static char sccsid[] = "@(#)input.c 5.2 (Berkeley) 10/22/87"; 1232471Sbostic #endif not lint 1332471Sbostic 1432471Sbostic #include "include.h" 1532471Sbostic 1632471Sbostic #define MAXRULES 6 1732471Sbostic #define MAXDEPTH 15 1832471Sbostic 1932471Sbostic #define RETTOKEN '\n' 2032471Sbostic #ifdef SYSV 2132471Sbostic #define CRTOKEN '\r' 2232471Sbostic #endif 2332471Sbostic #define REDRAWTOKEN '\014' /* CTRL(L) */ 2432471Sbostic #define SHELLTOKEN '!' 2532471Sbostic #define HELPTOKEN '?' 2632471Sbostic #define ALPHATOKEN 256 2732471Sbostic #define NUMTOKEN 257 2832471Sbostic 2932471Sbostic typedef struct { 3032471Sbostic int token; 3132471Sbostic int to_state; 3232471Sbostic char *str; 3332471Sbostic char *(*func)(); 3432471Sbostic } RULE; 3532471Sbostic 3632471Sbostic typedef struct { 3732471Sbostic int num_rules; 3832471Sbostic RULE *rule; 3932471Sbostic } STATE; 4032471Sbostic 4132471Sbostic typedef struct { 4232471Sbostic char str[20]; 4332471Sbostic int state; 4432471Sbostic int rule; 4532471Sbostic int ch; 4632471Sbostic int pos; 4732471Sbostic } STACK; 4832471Sbostic 4932471Sbostic #define T_RULE stack[level].rule 5032471Sbostic #define T_STATE stack[level].state 5132471Sbostic #define T_STR stack[level].str 5232471Sbostic #define T_POS stack[level].pos 5332471Sbostic #define T_CH stack[level].ch 5432471Sbostic 5532471Sbostic #define NUMELS(a) (sizeof (a) / sizeof (*(a))) 5632471Sbostic 5732471Sbostic #define NUMSTATES NUMELS(st) 5832471Sbostic 5932471Sbostic char *setplane(), *circle(), *left(), *right(), *Left(), *Right(), 6032471Sbostic *beacon(), *ex_it(), *climb(), *descend(), *setalt(), *setrelalt(), 6132471Sbostic *benum(), *to_dir(), *rel_dir(), *delayb(), *mark(), *unmark(), 6232471Sbostic *airport(), *turn(), *ignore(); 6332471Sbostic 6432471Sbostic RULE state0[] = { { ALPHATOKEN, 1, "%c:", setplane}, 6532471Sbostic { RETTOKEN, -1, "", NULL }, 6632471Sbostic #ifdef SYSV 6732471Sbostic { CRTOKEN, -1, "", NULL }, 6832471Sbostic #endif 6932471Sbostic { HELPTOKEN, 12, " [a-z]<ret>", NULL }}, 7032471Sbostic state1[] = { { 't', 2, " turn", turn }, 7132471Sbostic { 'a', 3, " altitude:", NULL }, 7232471Sbostic { 'c', 4, " circle", circle }, 7332471Sbostic { 'm', 7, " mark", mark }, 7432471Sbostic { 'u', 7, " unmark", unmark }, 7532471Sbostic { 'i', 7, " ignore", ignore }, 7632471Sbostic { HELPTOKEN, 12, " tacmui", NULL }}, 7732471Sbostic state2[] = { { 'l', 6, " left", left }, 7832471Sbostic { 'r', 6, " right", right }, 7932471Sbostic { 'L', 4, " left 90", Left }, 8032471Sbostic { 'R', 4, " right 90", Right }, 8132471Sbostic { 't', 11, " towards", NULL }, 8232471Sbostic { 'w', 4, " to 0", to_dir }, 8332471Sbostic { 'e', 4, " to 45", to_dir }, 8432471Sbostic { 'd', 4, " to 90", to_dir }, 8532471Sbostic { 'c', 4, " to 135", to_dir }, 8632471Sbostic { 'x', 4, " to 180", to_dir }, 8732471Sbostic { 'z', 4, " to 225", to_dir }, 8832471Sbostic { 'a', 4, " to 270", to_dir }, 8932471Sbostic { 'q', 4, " to 315", to_dir }, 9032471Sbostic { HELPTOKEN, 12, " lrLRt<dir>", NULL }}, 9132471Sbostic state3[] = { { '+', 10, " climb", climb }, 9232471Sbostic { 'c', 10, " climb", climb }, 9332471Sbostic { '-', 10, " descend", descend }, 9432471Sbostic { 'd', 10, " descend", descend }, 9532471Sbostic { NUMTOKEN, 7, " %c000 feet", setalt }, 9632471Sbostic { HELPTOKEN, 12, " +-cd[0-9]", NULL }}, 9732471Sbostic state4[] = { { '@', 9, " at", NULL }, 9832471Sbostic { 'a', 9, " at", NULL }, 9932471Sbostic { RETTOKEN, -1, "", NULL }, 10032471Sbostic #ifdef SYSV 10132471Sbostic { CRTOKEN, -1, "", NULL }, 10232471Sbostic #endif 10332471Sbostic { HELPTOKEN, 12, " @a<ret>", NULL }}, 10432471Sbostic state5[] = { { NUMTOKEN, 7, "%c", delayb }, 10532471Sbostic { HELPTOKEN, 12, " [0-9]", NULL }}, 10632471Sbostic state6[] = { { '@', 9, " at", NULL }, 10732471Sbostic { 'a', 9, " at", NULL }, 10832471Sbostic { 'w', 4, " 0", rel_dir }, 10932471Sbostic { 'e', 4, " 45", rel_dir }, 11032471Sbostic { 'd', 4, " 90", rel_dir }, 11132471Sbostic { 'c', 4, " 135", rel_dir }, 11232471Sbostic { 'x', 4, " 180", rel_dir }, 11332471Sbostic { 'z', 4, " 225", rel_dir }, 11432471Sbostic { 'a', 4, " 270", rel_dir }, 11532471Sbostic { 'q', 4, " 315", rel_dir }, 11632471Sbostic { RETTOKEN, -1, "", NULL }, 11732471Sbostic #ifdef SYSV 11832471Sbostic { CRTOKEN, -1, "", NULL }, 11932471Sbostic #endif 12032471Sbostic { HELPTOKEN, 12, " @a<dir><ret>",NULL }}, 12132471Sbostic state7[] = { { RETTOKEN, -1, "", NULL }, 12232471Sbostic #ifdef SYSV 12332471Sbostic { CRTOKEN, -1, "", NULL }, 12432471Sbostic #endif 12532471Sbostic { HELPTOKEN, 12, " <ret>", NULL }}, 12632471Sbostic state8[] = { { NUMTOKEN, 4, "%c", benum }, 12732471Sbostic { HELPTOKEN, 12, " [0-9]", NULL }}, 12832471Sbostic state9[] = { { 'b', 5, " beacon #", NULL }, 12932471Sbostic { '*', 5, " beacon #", NULL }, 13032471Sbostic { HELPTOKEN, 12, " b*", NULL }}, 13132471Sbostic state10[] = { { NUMTOKEN, 7, " %c000 ft", setrelalt}, 13232471Sbostic { HELPTOKEN, 12, " [0-9]", NULL }}, 13332471Sbostic state11[] = { { 'b', 8, " beacon #", beacon }, 13432471Sbostic { '*', 8, " beacon #", beacon }, 13532471Sbostic { 'e', 8, " exit #", ex_it }, 13632471Sbostic { 'a', 8, " airport #", airport }, 13732471Sbostic { HELPTOKEN, 12, " b*ea", NULL }}, 13832471Sbostic state12[] = { { -1, -1, "", NULL }}; 13932471Sbostic 14032471Sbostic #define DEF_STATE(s) { NUMELS(s), (s) } 14132471Sbostic 14232471Sbostic STATE st[] = { 14332471Sbostic DEF_STATE(state0), DEF_STATE(state1), DEF_STATE(state2), 14432471Sbostic DEF_STATE(state3), DEF_STATE(state4), DEF_STATE(state5), 14532471Sbostic DEF_STATE(state6), DEF_STATE(state7), DEF_STATE(state8), 14632471Sbostic DEF_STATE(state9), DEF_STATE(state10), DEF_STATE(state11), 14732471Sbostic DEF_STATE(state12) 14832471Sbostic }; 14932471Sbostic 15032471Sbostic PLANE p; 15132471Sbostic STACK stack[MAXDEPTH]; 15232471Sbostic int level; 15332471Sbostic int tval; 15432471Sbostic int dest_type, dest_no, dir; 15532471Sbostic 15632471Sbostic pop() 15732471Sbostic { 15832471Sbostic if (level == 0) 15932471Sbostic return (-1); 16032471Sbostic level--; 16132471Sbostic 16232471Sbostic ioclrtoeol(T_POS); 16332471Sbostic 16432471Sbostic strcpy(T_STR, ""); 16532471Sbostic T_RULE = -1; 16632471Sbostic T_CH = -1; 16732471Sbostic return (0); 16832471Sbostic } 16932471Sbostic 17032471Sbostic rezero() 17132471Sbostic { 17232471Sbostic iomove(0); 17332471Sbostic 17432471Sbostic level = 0; 17532471Sbostic T_STATE = 0; 17632471Sbostic T_RULE = -1; 17732471Sbostic T_CH = -1; 17832471Sbostic T_POS = 0; 17932471Sbostic strcpy(T_STR, ""); 18032471Sbostic } 18132471Sbostic 18232471Sbostic push(ruleno, ch) 18332471Sbostic { 18432471Sbostic int newstate, newpos; 18532471Sbostic 186*32472Sbostic (void)sprintf(T_STR, st[T_STATE].rule[ruleno].str, tval); 18732471Sbostic T_RULE = ruleno; 18832471Sbostic T_CH = ch; 18932471Sbostic newstate = st[T_STATE].rule[ruleno].to_state; 19032471Sbostic newpos = T_POS + strlen(T_STR); 19132471Sbostic 19232471Sbostic ioaddstr(T_POS, T_STR); 19332471Sbostic 19432471Sbostic if (level == 0) 19532471Sbostic ioclrtobot(); 19632471Sbostic level++; 19732471Sbostic T_STATE = newstate; 19832471Sbostic T_POS = newpos; 19932471Sbostic T_RULE = -1; 20032471Sbostic strcpy(T_STR, ""); 20132471Sbostic } 20232471Sbostic 20332471Sbostic getcommand() 20432471Sbostic { 20532471Sbostic int c, i, done; 20632471Sbostic char *s, *(*func)(); 20732471Sbostic PLANE *pp; 20832471Sbostic 20932471Sbostic rezero(); 21032471Sbostic 21132471Sbostic do { 21232471Sbostic c = gettoken(); 21332471Sbostic if (c == tty_new.sg_erase) { 21432471Sbostic if (pop() < 0) 21532471Sbostic noise(); 21632471Sbostic } else if (c == tty_new.sg_kill) { 21732471Sbostic while (pop() >= 0) 21832471Sbostic ; 21932471Sbostic } else { 22032471Sbostic done = 0; 22132471Sbostic for (i = 0; i < st[T_STATE].num_rules; i++) { 22232471Sbostic if (st[T_STATE].rule[i].token == c || 22332471Sbostic st[T_STATE].rule[i].token == tval) { 22432471Sbostic push(i, (c >= ALPHATOKEN) ? tval : c); 22532471Sbostic done = 1; 22632471Sbostic break; 22732471Sbostic } 22832471Sbostic } 22932471Sbostic if (!done) 23032471Sbostic noise(); 23132471Sbostic } 23232471Sbostic } while (T_STATE != -1); 23332471Sbostic 23432471Sbostic if (level == 1) 23532471Sbostic return (1); /* forced update */ 23632471Sbostic 23732471Sbostic dest_type = T_NODEST; 23832471Sbostic 23932471Sbostic for (i = 0; i < level; i++) { 24032471Sbostic func = st[stack[i].state].rule[stack[i].rule].func; 24132471Sbostic if (func != NULL) 24232471Sbostic if ((s = (*func)(stack[i].ch)) != NULL) { 24332471Sbostic ioerror(stack[i].pos, strlen(stack[i].str), s); 24432471Sbostic return (-1); 24532471Sbostic } 24632471Sbostic } 24732471Sbostic 24832471Sbostic pp = findplane(p.plane_no); 24932471Sbostic if (pp->new_altitude != p.new_altitude) 25032471Sbostic pp->new_altitude = p.new_altitude; 25132471Sbostic else if (pp->status != p.status) 25232471Sbostic pp->status = p.status; 25332471Sbostic else { 25432471Sbostic pp->new_dir = p.new_dir; 25532471Sbostic pp->delayd = p.delayd; 25632471Sbostic pp->delayd_no = p.delayd_no; 25732471Sbostic } 25832471Sbostic return (0); 25932471Sbostic } 26032471Sbostic 26132471Sbostic noise() 26232471Sbostic { 26332471Sbostic putchar('\07'); 26432471Sbostic fflush(stdout); 26532471Sbostic } 26632471Sbostic 26732471Sbostic gettoken() 26832471Sbostic { 26932471Sbostic while ((tval = getAChar()) == REDRAWTOKEN || tval == SHELLTOKEN) 27032471Sbostic { 27132471Sbostic if (tval == SHELLTOKEN) 27232471Sbostic { 27332471Sbostic #ifdef BSD 27432471Sbostic struct itimerval itv; 27532471Sbostic itv.it_value.tv_sec = 0; 27632471Sbostic itv.it_value.tv_usec = 0; 27732471Sbostic setitimer(ITIMER_REAL, &itv, NULL); 27832471Sbostic #endif 27932471Sbostic #ifdef SYSV 28032471Sbostic int aval; 28132471Sbostic aval = alarm(0); 28232471Sbostic #endif 28332471Sbostic if (fork() == 0) /* child */ 28432471Sbostic { 28532471Sbostic char *shell, *base, *getenv(), *strrchr(); 28632471Sbostic 28732471Sbostic setuid(getuid()); /* turn off setuid bit */ 28832471Sbostic done_screen(); 28932471Sbostic 29032471Sbostic /* run user's favorite shell */ 29132471Sbostic if ((shell = getenv("SHELL")) != NULL) 29232471Sbostic { 29332471Sbostic base = strrchr(shell, '/'); 29432471Sbostic if (base == NULL) 29532471Sbostic base = shell; 29632471Sbostic else 29732471Sbostic base++; 29832471Sbostic execl(shell, base, 0); 29932471Sbostic } 30032471Sbostic else 30132471Sbostic execl("/bin/sh", "sh", 0); 30232471Sbostic 30332471Sbostic exit(0); /* oops */ 30432471Sbostic } 30532471Sbostic 30632471Sbostic wait(0); 30732471Sbostic #ifdef BSD 30832471Sbostic ioctl(fileno(stdin), TIOCSETP, &tty_new); 30932471Sbostic itv.it_value.tv_sec = 0; 31032471Sbostic itv.it_value.tv_usec = 1; 31132471Sbostic itv.it_interval.tv_sec = sp->update_secs; 31232471Sbostic itv.it_interval.tv_usec = 0; 31332471Sbostic setitimer(ITIMER_REAL, &itv, NULL); 31432471Sbostic #endif 31532471Sbostic #ifdef SYSV 31632471Sbostic ioctl(fileno(stdin), TCSETAW, &tty_new); 31732471Sbostic alarm(aval); 31832471Sbostic #endif 31932471Sbostic } 32032471Sbostic redraw(); 32132471Sbostic } 32232471Sbostic 32332471Sbostic if (isdigit(tval)) 32432471Sbostic return (NUMTOKEN); 32532471Sbostic else if (isalpha(tval)) 32632471Sbostic return (ALPHATOKEN); 32732471Sbostic else 32832471Sbostic return (tval); 32932471Sbostic } 33032471Sbostic 33132471Sbostic char * 33232471Sbostic setplane(c) 33332471Sbostic { 33432471Sbostic PLANE *pp; 33532471Sbostic 33632471Sbostic pp = findplane(number(c)); 33732471Sbostic if (pp == NULL) 33832471Sbostic return ("Unknown Plane"); 33932471Sbostic bcopy(pp, &p, sizeof (p)); 34032471Sbostic p.delayd = 0; 34132471Sbostic return (NULL); 34232471Sbostic } 34332471Sbostic 34432471Sbostic char * 34532471Sbostic turn(c) 34632471Sbostic { 34732471Sbostic if (p.altitude == 0) 34832471Sbostic return ("Planes at airports may not change direction"); 34932471Sbostic return (NULL); 35032471Sbostic } 35132471Sbostic 35232471Sbostic char * 35332471Sbostic circle(c) 35432471Sbostic { 35532471Sbostic if (p.altitude == 0) 35632471Sbostic return ("Planes cannot circle on the ground"); 35732471Sbostic p.new_dir = MAXDIR; 35832471Sbostic return (NULL); 35932471Sbostic } 36032471Sbostic 36132471Sbostic char * 36232471Sbostic left(c) 36332471Sbostic { 36432471Sbostic dir = D_LEFT; 36532471Sbostic p.new_dir = p.dir - 1; 36632471Sbostic if (p.new_dir < 0) 36732471Sbostic p.new_dir += MAXDIR; 36832471Sbostic return (NULL); 36932471Sbostic } 37032471Sbostic 37132471Sbostic char * 37232471Sbostic right(c) 37332471Sbostic { 37432471Sbostic dir = D_RIGHT; 37532471Sbostic p.new_dir = p.dir + 1; 37632471Sbostic if (p.new_dir > MAXDIR) 37732471Sbostic p.new_dir -= MAXDIR; 37832471Sbostic return (NULL); 37932471Sbostic } 38032471Sbostic 38132471Sbostic char * 38232471Sbostic Left(c) 38332471Sbostic { 38432471Sbostic p.new_dir = p.dir - 2; 38532471Sbostic if (p.new_dir < 0) 38632471Sbostic p.new_dir += MAXDIR; 38732471Sbostic return (NULL); 38832471Sbostic } 38932471Sbostic 39032471Sbostic char * 39132471Sbostic Right(c) 39232471Sbostic { 39332471Sbostic p.new_dir = p.dir + 2; 39432471Sbostic if (p.new_dir > MAXDIR) 39532471Sbostic p.new_dir -= MAXDIR; 39632471Sbostic return (NULL); 39732471Sbostic } 39832471Sbostic 39932471Sbostic char * 40032471Sbostic delayb(c) 40132471Sbostic { 40232471Sbostic int xdiff, ydiff; 40332471Sbostic 40432471Sbostic c -= '0'; 40532471Sbostic 40632471Sbostic if (c >= sp->num_beacons) 40732471Sbostic return ("Unknown beacon"); 40832471Sbostic xdiff = sp->beacon[c].x - p.xpos; 40932471Sbostic xdiff = SGN(xdiff); 41032471Sbostic ydiff = sp->beacon[c].y - p.ypos; 41132471Sbostic ydiff = SGN(ydiff); 41232471Sbostic if (xdiff != displacement[p.dir].dx || ydiff != displacement[p.dir].dy) 41332471Sbostic return ("Beacon is not in flight path"); 41432471Sbostic p.delayd = 1; 41532471Sbostic p.delayd_no = c; 41632471Sbostic 41732471Sbostic if (dest_type != T_NODEST) { 41832471Sbostic switch (dest_type) { 41932471Sbostic case T_BEACON: 42032471Sbostic xdiff = sp->beacon[dest_no].x - sp->beacon[c].x; 42132471Sbostic ydiff = sp->beacon[dest_no].y - sp->beacon[c].y; 42232471Sbostic break; 42332471Sbostic case T_EXIT: 42432471Sbostic xdiff = sp->exit[dest_no].x - sp->beacon[c].x; 42532471Sbostic ydiff = sp->exit[dest_no].y - sp->beacon[c].y; 42632471Sbostic break; 42732471Sbostic case T_AIRPORT: 42832471Sbostic xdiff = sp->airport[dest_no].x - sp->beacon[c].x; 42932471Sbostic ydiff = sp->airport[dest_no].y - sp->beacon[c].y; 43032471Sbostic break; 43132471Sbostic default: 43232471Sbostic return ("Bad case in delayb! Get help!"); 43332471Sbostic break; 43432471Sbostic } 43532471Sbostic if (xdiff == 0 && ydiff == 0) 43632471Sbostic return ("Would already be there"); 43732471Sbostic p.new_dir = DIR_FROM_DXDY(xdiff, ydiff); 43832471Sbostic if (p.new_dir == p.dir) 43932471Sbostic return ("Already going in that direction"); 44032471Sbostic } 44132471Sbostic return (NULL); 44232471Sbostic } 44332471Sbostic 44432471Sbostic char * 44532471Sbostic beacon(c) 44632471Sbostic { 44732471Sbostic dest_type = T_BEACON; 44832471Sbostic return (NULL); 44932471Sbostic } 45032471Sbostic 45132471Sbostic char * 45232471Sbostic ex_it(c) 45332471Sbostic { 45432471Sbostic dest_type = T_EXIT; 45532471Sbostic return (NULL); 45632471Sbostic } 45732471Sbostic 45832471Sbostic char * 45932471Sbostic airport(c) 46032471Sbostic { 46132471Sbostic dest_type = T_AIRPORT; 46232471Sbostic return (NULL); 46332471Sbostic } 46432471Sbostic 46532471Sbostic char * 46632471Sbostic climb(c) 46732471Sbostic { 46832471Sbostic dir = D_UP; 46932471Sbostic return (NULL); 47032471Sbostic } 47132471Sbostic 47232471Sbostic char * 47332471Sbostic descend(c) 47432471Sbostic { 47532471Sbostic dir = D_DOWN; 47632471Sbostic return (NULL); 47732471Sbostic } 47832471Sbostic 47932471Sbostic char * 48032471Sbostic setalt(c) 48132471Sbostic { 48232471Sbostic if ((p.altitude == c - '0') && (p.new_altitude == p.altitude)) 48332471Sbostic return ("Already at that altitude"); 48432471Sbostic p.new_altitude = c - '0'; 48532471Sbostic return (NULL); 48632471Sbostic } 48732471Sbostic 48832471Sbostic char * 48932471Sbostic setrelalt(c) 49032471Sbostic { 49132471Sbostic if (c == 0) 49232471Sbostic return ("altitude not changed"); 49332471Sbostic 49432471Sbostic switch (dir) { 49532471Sbostic case D_UP: 49632471Sbostic p.new_altitude = p.altitude + c - '0'; 49732471Sbostic break; 49832471Sbostic case D_DOWN: 49932471Sbostic p.new_altitude = p.altitude - (c - '0'); 50032471Sbostic break; 50132471Sbostic default: 50232471Sbostic return ("Unknown case in setrelalt! Get help!"); 50332471Sbostic break; 50432471Sbostic } 50532471Sbostic if (p.new_altitude < 0) 50632471Sbostic return ("Altitude would be too low"); 50732471Sbostic else if (p.new_altitude > 9) 50832471Sbostic return ("Altitude would be too high"); 50932471Sbostic return (NULL); 51032471Sbostic } 51132471Sbostic 51232471Sbostic char * 51332471Sbostic benum(c) 51432471Sbostic { 51532471Sbostic dest_no = c -= '0'; 51632471Sbostic 51732471Sbostic switch (dest_type) { 51832471Sbostic case T_BEACON: 51932471Sbostic if (c >= sp->num_beacons) 52032471Sbostic return ("Unknown beacon"); 52132471Sbostic p.new_dir = DIR_FROM_DXDY(sp->beacon[c].x - p.xpos, 52232471Sbostic sp->beacon[c].y - p.ypos); 52332471Sbostic break; 52432471Sbostic case T_EXIT: 52532471Sbostic if (c >= sp->num_exits) 52632471Sbostic return ("Unknown exit"); 52732471Sbostic p.new_dir = DIR_FROM_DXDY(sp->exit[c].x - p.xpos, 52832471Sbostic sp->exit[c].y - p.ypos); 52932471Sbostic break; 53032471Sbostic case T_AIRPORT: 53132471Sbostic if (c >= sp->num_airports) 53232471Sbostic return ("Unknown airport"); 53332471Sbostic p.new_dir = DIR_FROM_DXDY(sp->airport[c].x - p.xpos, 53432471Sbostic sp->airport[c].y - p.ypos); 53532471Sbostic break; 53632471Sbostic default: 53732471Sbostic return ("Unknown case in benum! Get help!"); 53832471Sbostic break; 53932471Sbostic } 54032471Sbostic return (NULL); 54132471Sbostic } 54232471Sbostic 54332471Sbostic char * 54432471Sbostic to_dir(c) 54532471Sbostic { 54632471Sbostic p.new_dir = dir_no(c); 54732471Sbostic return (NULL); 54832471Sbostic } 54932471Sbostic 55032471Sbostic char * 55132471Sbostic rel_dir(c) 55232471Sbostic { 55332471Sbostic int angle; 55432471Sbostic 55532471Sbostic angle = dir_no(c); 55632471Sbostic switch (dir) { 55732471Sbostic case D_LEFT: 55832471Sbostic p.new_dir = p.dir - angle; 55932471Sbostic if (p.new_dir < 0) 56032471Sbostic p.new_dir += MAXDIR; 56132471Sbostic break; 56232471Sbostic case D_RIGHT: 56332471Sbostic p.new_dir = p.dir + angle; 56432471Sbostic if (p.new_dir >= MAXDIR) 56532471Sbostic p.new_dir -= MAXDIR; 56632471Sbostic break; 56732471Sbostic default: 56832471Sbostic return ("Bizarre direction in rel_dir! Get help!"); 56932471Sbostic break; 57032471Sbostic } 57132471Sbostic return (NULL); 57232471Sbostic } 57332471Sbostic 57432471Sbostic char * 57532471Sbostic mark(c) 57632471Sbostic { 57732471Sbostic if (p.altitude == 0) 57832471Sbostic return ("Cannot mark planes on the ground"); 57932471Sbostic if (p.status == S_MARKED) 58032471Sbostic return ("Already marked"); 58132471Sbostic p.status = S_MARKED; 58232471Sbostic return (NULL); 58332471Sbostic } 58432471Sbostic 58532471Sbostic char * 58632471Sbostic unmark(c) 58732471Sbostic { 58832471Sbostic if (p.altitude == 0) 58932471Sbostic return ("Cannot unmark planes on the ground"); 59032471Sbostic if (p.status == S_UNMARKED) 59132471Sbostic return ("Already unmarked"); 59232471Sbostic p.status = S_UNMARKED; 59332471Sbostic return (NULL); 59432471Sbostic } 59532471Sbostic 59632471Sbostic char * 59732471Sbostic ignore(c) 59832471Sbostic { 59932471Sbostic if (p.altitude == 0) 60032471Sbostic return ("Cannot ignore planes on the ground"); 60132471Sbostic if (p.status == S_IGNORED) 60232471Sbostic return ("Already ignored"); 60332471Sbostic p.status = S_IGNORED; 60432471Sbostic return (NULL); 60532471Sbostic } 60632471Sbostic 60732471Sbostic dir_no(ch) 60832471Sbostic char ch; 60932471Sbostic { 61032471Sbostic int dir; 61132471Sbostic 61232471Sbostic switch (ch) { 61332471Sbostic case 'w': dir = 0; break; 61432471Sbostic case 'e': dir = 1; break; 61532471Sbostic case 'd': dir = 2; break; 61632471Sbostic case 'c': dir = 3; break; 61732471Sbostic case 'x': dir = 4; break; 61832471Sbostic case 'z': dir = 5; break; 61932471Sbostic case 'a': dir = 6; break; 62032471Sbostic case 'q': dir = 7; break; 62132471Sbostic default: 62232471Sbostic fprintf(stderr, "bad character in dir_no\n"); 62332471Sbostic break; 62432471Sbostic } 62532471Sbostic return (dir); 62632471Sbostic } 627