/* aread.c: read and parse an airspace file */ #include <stdio.h> #include <sys/ttyio.h> #include <sys/param.h> #include <sys/timeb.h> #include <ctype.h> #include <signal.h> #include "ahdr.h" /* The following section reads a file containing info on the * current airspace. A sample looks like: Apple1 size: 15x24 airway: 1=(0,13) [20-30] SE 8=(10,23) [10-5] airway: 0=(4,0) S 9=(4,23) airway: 2=(14,15) NW 7=(0,1) airway: 3=(0,9) NE 6=(9,0) airway: 4=(14,7) SW 5=(0,21) airport: %=(4,11) S airport: #=(10,11) NE navaid: *=(4,5) navaid: *=(4,17) * where the airspace id starts in the first column, and everything else * is indented one tab and has syntax exactly as shown. * Numbers in square brackets are proportion of entries-exits from-to this * point. Default for normal places is 10 and default for airports is 16. */ /* note: [prob] code is obsolete */ #define I_SIZE 1 /* these are the tokens for the airspace identifiers*/ #define I_AIRWAY 2 #define I_AIRPORT 3 #define I_NAVAID 4 struct namestr { char *i_name; int i_token; } name[] = { "size", I_SIZE, "airway", I_AIRWAY, "airport", I_AIRPORT, "navaid", I_NAVAID, 0 }; extern int npaths; /* number of paths in the path file */ extern int maxflow; extern struct flow fpath[MAXPATHS]; #define BUFSIZE 100 extern struct pstruct entry[EMAX],airport[AMAX],navaid[NMAX]; extern char *airspace,*airfile,*flowfile; extern int height,width; extern char screen[MAXWIDTH][MAXHEIGHT]; extern int nentry,nairport,nnavaid; extern int inawtot,inaptot,outawtot,outaptot; char *strchr(); readspace() /* read the airspace file to get user's desired airspace */ { FILE *asfile; char lbuf[BUFSIZE]; /* line from the airspace file */ char ibuf[BUFSIZE]; /* airspace identifier */ char *c; struct namestr *n; int i,org,dst; FILE *flowstream; struct flow *path; if ((asfile = fopen(airfile,"r")) == NULL) err("Cannot open airspace file, %s\n",airfile); do /* scan through the file until we get the right airspace */ { if (fgets(lbuf,BUFSIZE,asfile) == NULL) err("Couldn't find airspace %s in %s\n",airspace,airfile); if (lbuf[0] == '\t') continue; /* not an airspace id */ for (c=lbuf; *c; c++) if (*c == '\n') *c = 0; /*kill newline*/ } while (strcmp(lbuf,airspace)); /* next consider each line of this airspace in turn */ while (fgets(lbuf,BUFSIZE,asfile) != NULL & lbuf[0] == '\t') { for (c=lbuf; *c == '\t' || *c == ' '; c++); /* skip blanks */ strcpy(ibuf,c); if ((c = strchr(ibuf,':')) == 0) err("No colon in %s, line %s",airfile,lbuf); *c = 0; /* terminate the command id */ for (n = name; n->i_name != 0; n++) /* get symbol */ if (strcmp(ibuf, n->i_name) == 0) break; switch(n->i_token) { case I_SIZE: sizeread(lbuf); break; case I_AIRWAY: airwayread(lbuf); break; case I_AIRPORT: apread(lbuf); break; case I_NAVAID: navaidread(lbuf); break; default: err("Unrecognized id in %s, line %s", airfile,lbuf); } } fclose(asfile); /* now put commas on all the airways */ for (i=0; i<nentry; i++) /* go both ways -- doubles the work */ { int x,y,dx,dy; x = entry[i].p_x; y = entry[i].p_y; dx = entry[i].p_dx; dy = entry[i].p_dy; while (x>=0 && y>=0 && x<width && y<height) { if (screen[x][y] == '.') screen[x][y] = ','; x += dx; y += dy; } } if (!flowfile) /* if no flow file specified, look for one */ { char *s,*t; static char flowbuf[80]; FILE *test; if (*(t = airfile) == '/') /* full airfile path? */ { for (s = flowbuf; *s++ = *t++; ); /* copy airfile */ while (*--s != '/'); /* back to last slash */ s++; } else s = flowbuf; for (t = airspace; *t; *s++ = *t++);/*air space*/ for (t = ".flow"; *s++ = *t++; ); if ((test = fopen(flowbuf,"r")) != NULL) /* it's there */ { fclose(test); flowfile = flowbuf; } } if (flowfile) /* flow control */ { maxflow = 0; if ((flowstream = fopen(flowfile,"r")) == NULL) err("Cannot open flow control file: %s\n",flowfile); path = &fpath[npaths = 0]; while (fgets(lbuf,BUFSIZE,flowstream) != NULL) { if (lbuf[0] == '\n') continue; /* ignore newlines */ org = *(c = lbuf); /* 1st char is origin */ if (*++c != '-') err("Path format: x->y 123\nYou gave me %s\n", lbuf); if (*++c != '>') err("Path format: x->y 123\nYou gave me %s\n", lbuf); dst = *++c; /* we need to code these in their flightpath() fmt */ pcode(org,path,1); pcode(dst,path,0); path->f_freq = atoi(++c); /* get relative freq*/ maxflow += path->f_freq; /* total frequency */ /* read distances for minimal paths */ while (*++c) if (*c == ' ') break; /* next fld */ path->f_cmds = (*c == 0? 1 : atoi(c)); if (*c) while (*++c) if (*c != ' ') break; if (*c) while (*++c) if (*c == ' ') break; path->f_dist[0] = (*c == 0? 1 : atoi(c)); for (i=1;i<7;i++) path->f_dist[i] = path->f_dist[0]; for (i = 7; i < NALT; i++) { if (*c) while (*++c) if (*c != ' ') break; if (*c) while (*++c) if (*c == ' ') break; if (*c) path->f_dist[i] = atoi(c); else path->f_dist[i] = path->f_dist[i-1]; } path++; npaths++; } fclose(flowstream); } } pcode(c,path,from) /* find flightplan() entry/exit code for character c */ char c; struct flow *path; int from; { int i; for (i=0; i<nentry; i++) if (c == entry[i].p_sym) break; if (i<nentry) { if (from) { path->f_from = i; path->f_fair = 0; } else { path->f_to = i; path->f_tair = 0; } return; } for (i=0; i<nairport; i++) if (c == airport[i].p_sym) break; if (i<nairport) { if (from) { path->f_from = i; path->f_fair = 1; } else { path->f_to = i; path->f_tair = 1; } return; } err("Unrecognized point %c in path file.\n",c); } sizeread(buf) char *buf; { char *c; c = strchr(buf,':'); /* previously checked for existence */ width = atoi(++c); if ((c = strchr(buf,'x')) == 0) err("A size line must be of the form size: 15x25"); height = atoi(++c); if (width > MAXWIDTH || width < MINWIDTH) err("Width must be in the range %d to %d",MINWIDTH,MAXWIDTH); if (height > MAXHEIGHT || height < MINHEIGHT) err("Height must be in the range %d to %d",MINHEIGHT,MAXHEIGHT); } char * getpoint(buf,p) /* read an entry point, airport, or beacon from file */ char *buf; struct pstruct *p; { char *c; int i; c = strchr(buf,'='); if (c == 0) return(0); p->p_sym = *--c; c = strchr(c,'('); if (c == 0) return(0); p->p_x = atoi(++c); c = strchr(c,','); if (c == 0) return(0); p->p_y = atoi(++c); c = strchr(c,')'); if (c == 0) return(0); screen[p->p_x][p->p_y] = p->p_sym; ++c; /* space or return after ) */ /* note: [prob] code is obsolete */ if (*(c+1) == '[') /* if next char is [, then we have a proportion */ { p->p_inprop = atoi(c+2); c = strchr(c,'-'); if (c == 0) return(0); p->p_outprop = atoi(++c); c = strchr(c,']'); if (c == 0) return(0); c++; } return(c); } char * getdirec(c,p) char *c; struct pstruct *p; { while (*c != ' ' && *c && *c != '\n') { switch(*c++) { case 'N': p->p_dy = -1; break; case 'S': p->p_dy = 1; break; case 'E': p->p_dx = 1; break; case 'W': p->p_dx = -1; break; default : return(0); } } return(c); } airwayread(buf) char *buf; { char *c; struct pstruct *p,*q; p = &entry[nentry++]; p->p_inprop = p->p_outprop = 10; c = getpoint(buf,p); inawtot += p->p_inprop; outawtot += p->p_outprop; if (c == 0) err("Airway syntax error"); c = strchr(c,' '); /* now get direction */ if (c == 0) err("Airway syntax error"); p->p_dx = p->p_dy = 0; c = getdirec(++c,p); if (c == 0) err("Airway direction error"); q = &entry[nentry++]; q->p_inprop = q->p_outprop = 10; c = getpoint(c,q); inawtot += q->p_inprop; outawtot += q->p_outprop; if (c == 0) err("Airway syntax error"); q->p_dx = -p->p_dx; /* reverse direction from other entry */ q->p_dy = -p->p_dy; } apread(buf) char *buf; { char *c; struct pstruct *p; p = &airport[nairport++]; p->p_inprop = p->p_outprop = 26; c = getpoint(buf,p); inaptot += p->p_inprop; outaptot += p->p_outprop; if (c == 0) err("Airport syntax error"); p->p_dx = p->p_dy = 0; c = getdirec(++c,p); if (c == 0) err("Airport direction syntax error"); } navaidread(buf) char *buf; { if (getpoint(buf,&navaid[nnavaid++]) == 0) err("Navaid syntax error"); }