home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
MM1
/
UTIL
/
ZC.LZH
/
zc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-13
|
10KB
|
442 lines
/* ZipCode Version 1.0 */
/* (c) January, 1995 */
/* by Joel Mathew Hegberg */
/* The code below is released to the public domain for educational */
/* purposes. This program may not be sold for profit. */
#include <stdio.h>
#include <modes.h>
#include <sgstat.h>
#include <termcap.h>
#include <errno.h>
#define TCAPSLEN 400
#define BUFFSIZE 20
#define STDIN 0
#define STDOUT 1
#define UP_ARROW 400
#define DOWN_ARROW 401
#define LEFT_ARROW 402
#define RIGHT_ARROW 403
#define BACKSPACE 404
#define ENTER 0x0D
extern char *getenv();
int tputc(), touts(), putpad(), sigtrap();
char tcapbuf[TCAPSLEN];
short lines,columns,ospeed;
char PC_,
*UP, /* required by tgoto() */
*BC, /* required by tgoto() */
*CL,
*CM,
*KU,
*KD,
*KL,
*KR,
*KB,
*BL;
int keybuflen,keybufpos,keyflag=0,done=0,fsize,dpath;
char keybuff[BUFFSIZE];
struct sgbuf sgbuffer,oldbuffer;
main(argc,argv)
int argc;
char *argv[];
{
int keypress,t,ziplen=0,ziploc=0;
char keychar,zipcode[6],city[50],state[10],output[80];
if (open_zipfile()) /* open the zipcode file for read access */
{
fprintf(stderr,"Error opening '/dd/sys/zipcodes.txt' file for reading!\n");
exit(errno);
}
/* handle possible passed in arguments */
if (argc>1)
{
if (argv[1][0]=='-' || argc>2) /* request for help */
{
print_desc();
close_zipfile();
exit(0);
}
if (strlen(argv[1])!=5) /* must be a zipcode */
{
fprintf(stderr,"Zip Code must be 5 digits in length!\n");
close_zipfile();
exit(1);
}
strcpy(zipcode,argv[1]);
if (find_zipcode(zipcode,city,state)) printf("%s, %s.\n",city,state);
else printf("Zip Code not found!\n");
close_zipfile();
exit(0);
}
initialize_termcap(); /* find out user's terminal capabilities */
intercept(sigtrap); /* set up signal trap */
output[0]='\0'; /* Nothing available to copy to clipboard */
/* modify user's terminal settings, but remember original settings */
getstat(0,STDIN,&sgbuffer);
_strass(&oldbuffer,&sgbuffer,32);
sgbuffer.sg_pause=0;
sgbuffer.sg_echo=0;
sgbuffer.sg_eofch='\0';
setstat(0,STDIN,&sgbuffer);
/* set up screen */
putpad(CL);
putpad(tgoto(CM,0,0));
for(t=0;t<columns;t++) tputc('=');
putpad(tgoto(CM,0,1));
for(t=0;t<columns;t++) tputc('=');
center_text("- ZipCode Version 1.0 -",0);
center_text("- by Joel Mathew Hegberg -",1);
putpad(tgoto(CM,0,lines-2));
touts("'Q'uit, 'C'lear, 'Y' to copy, <ENTER> to search.");
putpad(tgoto(CM,0,3));
touts("Zip Code: >>_____<<");
putpad(tgoto(CM,0,4));
touts("City, State:");
/* main loop */
while(!done)
{
putpad(tgoto(CM,ziploc+15,3));
if (keyflag==-1) keypress=process_key();
else
{
read(STDIN,&keychar,1);
keypress=process_key(keychar);
}
if (keypress && !done)
{
switch(keypress)
{
case 'Q':
case 'q':
case 'X':
case 'x': /* quit, exit, leave! */
done=1;
break;
case 'Y': /* Copy to OS-9 global clipboard */
case 'y': /* (cliplib.l required to compile) */
if (output[0]) store_clip_text(output,0,0,0);
else
{
if (BL) putpad(BL);
}
break;
case 'C':
case 'c': /* clear the zipcode field */
ziploc=0;
ziplen=0;
putpad(tgoto(15,3));
touts("_____");
break;
case LEFT_ARROW:
case BACKSPACE:
if (ziploc>0) ziploc--;
break;
case RIGHT_ARROW:
if (ziploc<ziplen) ziploc++;
break;
case ENTER:
if (ziplen!=5)
{
if (BL) putpad(BL);
}
else
{
zipcode[ziplen]='\0';
putpad(tgoto(CM,13,4));
for(t=0;t<60;t++) tputc(' ');
putpad(tgoto(CM,13,4));
if (find_zipcode(zipcode,city,state))
{
sprintf(output,"%s, %s.",city,state);
touts(output);
}
else
{
output[0]='\0';
touts("Zip Code not found!");
if (BL) putpad(BL);
}
ziploc=0;
}
break;
default:
if (keypress>='0' && keypress<='9' && ziploc<5)
{
tputc((char)keypress);
zipcode[ziploc++]=keypress;
if (ziploc>ziplen) ziplen=ziploc;
}
else
{
if (BL) putpad(BL);
}
break;
}
}
}
close_zipfile(); /* close the zipcode file */
putpad(tgoto(CM,0,lines-2));
for(t=0;t<columns;t++) tputc(' ');
putpad(tgoto(CM,0,6));
setstat(0,STDIN,&oldbuffer); /* restore user's original terminal settings */
}
int open_zipfile()
{
dpath=open("/dd/SYS/zipcodes.txt",S_IREAD);
if (dpath==-1) return(dpath);
fsize=_gs_size(dpath);
return(0);
}
close_zipfile()
{
close(dpath);
}
/* find_zipcode() returns 1 if found, 0 if not found. */
/* I used a standard, very fast binary search algorithm. */
/* -- Joel Mathew Hegberg */
int find_zipcode(zipcode,city,state)
char *zipcode,*city,*state;
{
register int loc,start,end,t;
register char *dloc;
char data[101],lasttry='\0';
city[0]='\0';
state[0]='\0';
start=0;
end=fsize-1;
while(((end-start)>5 && start<end) || !lasttry)
{
if (end-start<6)
{
lasttry='\x01';
loc=0;
}
else loc=(end-start)/2+start;
lseek(dpath,(long)loc,0);
read(dpath,data,100);
data[100]='\0';
dloc=data;
if (!lasttry)
{
while(*dloc!='\x0d' && *dloc) dloc++;
dloc++;
}
if (*dloc)
{
t=strncmp(zipcode,dloc,5);
if (!t)
{
extract_citystate(dloc+6,city,state);
break;
}
if (t<0) end=loc;
else start=loc;
}
}
if (*city) return(1);
return(0);
}
/* move the city & state info to their proper locations */
extract_citystate(dloc,city,state)
char *dloc,*city,*state;
{
char *tmp;
for(tmp=city;*dloc!='\x09';tmp++,dloc++) *tmp=*dloc;
*tmp='\0';
dloc++;
for(tmp=state;*dloc!='\x0d';tmp++,dloc++) *tmp=*dloc;
*tmp='\0';
}
center_text(text,y)
char *text;
int y;
{
putpad(tgoto(CM,(columns-strlen(text))/2,y));
touts(text);
}
/* termcap-aware key input handling code */
int process_key(key)
char key;
{
int retkey,t;
switch(keyflag)
{
case -1:
retkey=(int)keybuff[keybufpos++];
if (!(--keybuflen)) keyflag=0;
break;
case 0:
keybuff[0]=key;
keybufpos=1;
keybuflen=1;
t=compare_special();
if (!t) retkey=(int)key;
else
{
if (t==1)
{
retkey=0;
keyflag=1;
}
else retkey=t;
}
break;
case 1:
keybuff[keybufpos++]=key;
keybuflen++;
t=compare_special();
if (!t)
{
keyflag=-1;
retkey=keybufpos=0;
}
else
{
if (t==1) retkey=0;
else
{
retkey=t;
keyflag=0;
}
}
break;
}
return(retkey);
}
int compare_special()
{
int t=0;
keybuff[keybufpos]='\0';
if (!strcmp(keybuff,KU)) t=UP_ARROW;
if (!strcmp(keybuff,KD)) t=DOWN_ARROW;
if (!strcmp(keybuff,KL)) t=LEFT_ARROW;
if (!strcmp(keybuff,KR)) t=RIGHT_ARROW;
if (!strcmp(keybuff,KB)) t=BACKSPACE;
if (t) return(t);
if (!strncmp(keybuff,KU,keybuflen)) t=1;
if (!strncmp(keybuff,KD,keybuflen)) t=1;
if (!strncmp(keybuff,KL,keybuflen)) t=1;
if (!strncmp(keybuff,KR,keybuflen)) t=1;
if (!strncmp(keybuff,KB,keybuflen)) t=1;
return(t);
}
initialize_termcap()
{
char tcbuf[1024],*term_type,*temp,*ptr;
if ((term_type=getenv("TERM"))==NULL)
{
fprintf(stderr,"Environment variable TERM not defined.\n");
exit(1);
}
if (tgetent(tcbuf,term_type)<=0)
{
fprintf(stderr,"Unknown terminal type '%s'.\n",term_type);
exit(1);
}
ptr=tcapbuf;
if (temp=tgetstr("PC",&ptr)) PC_=*temp;
CL=tgetstr("cl",&ptr);
CM=tgetstr("cm",&ptr);
KU=tgetstr("ku",&ptr);
KD=tgetstr("kd",&ptr);
KL=tgetstr("kl",&ptr);
KR=tgetstr("kr",&ptr);
KB=tgetstr("kb",&ptr);
BL=tgetstr("bl",&ptr);
UP=tgetstr("up",&ptr);
lines=tgetnum("li");
columns=tgetnum("co");
ospeed=0;
if (lines<1 || columns<1)
{
fprintf(stderr,"No rows or columns!\n");
exit(1);
}
if (!(CL && CM && KL && KR && KB && UP))
{
fprintf(stderr,"Incomplete termcap entry.\n");
fprintf(stderr,"Requires cl, cm, kl, kr, kb, up.\n");
exit(1);
}
if (ptr>=&tcapbuf[TCAPSLEN])
{
fprintf(stderr,"Terminal description too big!\n");
exit(1);
}
}
int tputc(c)
char c;
{
return (write(STDOUT,&c,1));
}
touts(s)
char *s;
{
write(STDOUT,s,strlen(s));
}
putpad(s)
char *s;
{
tputs(s,1,tputc);
}
sigtrap(signal)
int signal;
{
done=1;
}
/* The help message: */
print_desc()
{
fprintf(stderr,"\nZipCode Version 1.0\n");
fprintf(stderr,"by Joel Mathew Hegberg.\n\n");
fprintf(stderr,"Syntax: zc {xxxxx}\n");
fprintf(stderr,"Function: Application program for looking up city/state information\n");
fprintf(stderr," to a corresponding zip code.\n");
fprintf(stderr," If a zip-code is passed in as an argument (xxxxx),\n");
fprintf(stderr," then ZipCode merely prints out the city/state.\n\n");
}
/* THE END */