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 >
C/C++ Source or Header  |  1995-01-13  |  10KB  |  442 lines

  1. /* ZipCode Version 1.0    */
  2. /* (c) January, 1995      */
  3. /* by Joel Mathew Hegberg */
  4.  
  5. /* The code below is released to the public domain for educational */
  6. /* purposes.  This program may not be sold for profit.             */
  7.  
  8. #include <stdio.h>
  9. #include <modes.h>
  10. #include <sgstat.h>
  11. #include <termcap.h>
  12. #include <errno.h>
  13.  
  14. #define TCAPSLEN 400
  15. #define BUFFSIZE  20
  16. #define STDIN      0
  17. #define STDOUT     1
  18.  
  19. #define UP_ARROW    400
  20. #define DOWN_ARROW  401
  21. #define LEFT_ARROW  402
  22. #define RIGHT_ARROW 403
  23. #define BACKSPACE   404
  24. #define ENTER       0x0D
  25.  
  26. extern char *getenv();
  27. int    tputc(), touts(), putpad(), sigtrap();
  28. char   tcapbuf[TCAPSLEN];
  29. short  lines,columns,ospeed;
  30.  
  31. char  PC_,
  32.     *UP,   /* required by tgoto() */
  33.     *BC,   /* required by tgoto() */
  34.     *CL,
  35.     *CM,
  36.     *KU,
  37.     *KD,
  38.     *KL,
  39.     *KR,
  40.     *KB,
  41.     *BL;
  42.  
  43. int    keybuflen,keybufpos,keyflag=0,done=0,fsize,dpath;
  44. char   keybuff[BUFFSIZE];
  45. struct sgbuf sgbuffer,oldbuffer;
  46.  
  47. main(argc,argv)
  48. int   argc;
  49. char *argv[];
  50. {
  51.    int  keypress,t,ziplen=0,ziploc=0;
  52.    char keychar,zipcode[6],city[50],state[10],output[80];
  53.    
  54.    if (open_zipfile())   /* open the zipcode file for read access */
  55.    {
  56.       fprintf(stderr,"Error opening '/dd/sys/zipcodes.txt' file for reading!\n");
  57.       exit(errno);
  58.    }
  59.    
  60.    /* handle possible passed in arguments */
  61.    if (argc>1)
  62.    {
  63.       if (argv[1][0]=='-' || argc>2)   /* request for help */
  64.       {
  65.          print_desc();
  66.          close_zipfile();
  67.          exit(0);
  68.       }
  69.       if (strlen(argv[1])!=5)   /* must be a zipcode */
  70.       {
  71.          fprintf(stderr,"Zip Code must be 5 digits in length!\n");
  72.          close_zipfile();
  73.          exit(1);
  74.       }
  75.       strcpy(zipcode,argv[1]);
  76.       if (find_zipcode(zipcode,city,state)) printf("%s, %s.\n",city,state);
  77.       else printf("Zip Code not found!\n");
  78.       close_zipfile();
  79.       exit(0);
  80.    }
  81.    
  82.    initialize_termcap();   /* find out user's terminal capabilities */
  83.    intercept(sigtrap);   /* set up signal trap */
  84.    output[0]='\0';   /* Nothing available to copy to clipboard */
  85.    
  86.    /* modify user's terminal settings, but remember original settings */
  87.    getstat(0,STDIN,&sgbuffer);
  88.    _strass(&oldbuffer,&sgbuffer,32);
  89.    sgbuffer.sg_pause=0;
  90.    sgbuffer.sg_echo=0;
  91.    sgbuffer.sg_eofch='\0';
  92.    setstat(0,STDIN,&sgbuffer);
  93.    
  94.    /* set up screen */
  95.    putpad(CL);
  96.    putpad(tgoto(CM,0,0));
  97.    for(t=0;t<columns;t++) tputc('=');
  98.    putpad(tgoto(CM,0,1));
  99.    for(t=0;t<columns;t++) tputc('=');
  100.    center_text("- ZipCode Version 1.0 -",0);
  101.    center_text("- by Joel Mathew Hegberg -",1);
  102.    putpad(tgoto(CM,0,lines-2));
  103.    touts("'Q'uit, 'C'lear, 'Y' to copy, <ENTER> to search.");
  104.    putpad(tgoto(CM,0,3));
  105.    touts("Zip Code:    >>_____<<");
  106.    putpad(tgoto(CM,0,4));
  107.    touts("City, State:");
  108.    
  109.    /* main loop */
  110.    while(!done)
  111.    {
  112.       putpad(tgoto(CM,ziploc+15,3));
  113.       if (keyflag==-1) keypress=process_key();
  114.       else
  115.       {
  116.          read(STDIN,&keychar,1);
  117.          keypress=process_key(keychar);
  118.       }
  119.       
  120.       if (keypress && !done)
  121.       {
  122.          switch(keypress)
  123.          {
  124.             case 'Q':
  125.             case 'q':
  126.             case 'X':
  127.             case 'x':   /* quit, exit, leave! */
  128.                done=1;
  129.                break;
  130.             case 'Y':   /* Copy to OS-9 global clipboard   */
  131.             case 'y':   /* (cliplib.l required to compile) */
  132.                if (output[0]) store_clip_text(output,0,0,0);
  133.                else
  134.                {
  135.                   if (BL) putpad(BL);
  136.                }
  137.                break;
  138.             case 'C':
  139.             case 'c':   /* clear the zipcode field */
  140.                ziploc=0;
  141.                ziplen=0;
  142.                putpad(tgoto(15,3));
  143.                touts("_____");
  144.                break;
  145.             case LEFT_ARROW:
  146.             case BACKSPACE:
  147.                if (ziploc>0) ziploc--;
  148.                break;
  149.             case RIGHT_ARROW:
  150.                if (ziploc<ziplen) ziploc++;
  151.                break;
  152.             case ENTER:
  153.                if (ziplen!=5)
  154.                {
  155.                     if (BL) putpad(BL);
  156.                }
  157.                else
  158.                {
  159.                   zipcode[ziplen]='\0';
  160.                   putpad(tgoto(CM,13,4));
  161.                   for(t=0;t<60;t++) tputc(' ');
  162.                   putpad(tgoto(CM,13,4));
  163.                   if (find_zipcode(zipcode,city,state))
  164.                   {
  165.                      sprintf(output,"%s, %s.",city,state);
  166.                      touts(output);
  167.                   }
  168.                   else
  169.                   {
  170.                      output[0]='\0';
  171.                      touts("Zip Code not found!");
  172.                      if (BL) putpad(BL);
  173.                   }
  174.                   ziploc=0;
  175.                }
  176.                break;
  177.             default:
  178.                if (keypress>='0' && keypress<='9' && ziploc<5)
  179.                {
  180.                   tputc((char)keypress);
  181.                   zipcode[ziploc++]=keypress;
  182.                   if (ziploc>ziplen) ziplen=ziploc;
  183.                }
  184.                else
  185.                {
  186.                     if (BL) putpad(BL);
  187.                }
  188.                break;
  189.          }
  190.       }
  191.    }
  192.    
  193.    close_zipfile();   /* close the zipcode file */
  194.    putpad(tgoto(CM,0,lines-2));
  195.    for(t=0;t<columns;t++) tputc(' ');
  196.    putpad(tgoto(CM,0,6));
  197.    setstat(0,STDIN,&oldbuffer);   /* restore user's original terminal settings */
  198. }
  199.  
  200. int open_zipfile()
  201. {
  202.    dpath=open("/dd/SYS/zipcodes.txt",S_IREAD);
  203.    if (dpath==-1) return(dpath);
  204.    fsize=_gs_size(dpath);
  205.    return(0);
  206. }
  207.  
  208. close_zipfile()
  209. {
  210.    close(dpath);
  211. }
  212.  
  213. /* find_zipcode() returns 1 if found, 0 if not found.    */
  214. /* I used a standard, very fast binary search algorithm. */
  215. /*   -- Joel Mathew Hegberg                              */
  216. int find_zipcode(zipcode,city,state)
  217. char *zipcode,*city,*state;
  218. {
  219.    register int   loc,start,end,t;
  220.    register char *dloc;
  221.    char data[101],lasttry='\0';
  222.    
  223.    city[0]='\0';
  224.    state[0]='\0';
  225.    start=0;
  226.    end=fsize-1;
  227.    while(((end-start)>5 && start<end) || !lasttry)
  228.    {
  229.       if (end-start<6)
  230.       {
  231.          lasttry='\x01';
  232.          loc=0;
  233.       }
  234.       else loc=(end-start)/2+start;
  235.       lseek(dpath,(long)loc,0);
  236.       read(dpath,data,100);
  237.       data[100]='\0';
  238.       dloc=data;
  239.       if (!lasttry)
  240.       {
  241.          while(*dloc!='\x0d' && *dloc) dloc++;
  242.          dloc++;
  243.       }
  244.       if (*dloc)
  245.       {
  246.          t=strncmp(zipcode,dloc,5);
  247.          if (!t)
  248.          {
  249.             extract_citystate(dloc+6,city,state);
  250.             break;
  251.          }
  252.          if (t<0) end=loc;
  253.          else start=loc;
  254.       }
  255.    }
  256.    if (*city) return(1);
  257.    return(0);
  258. }
  259.  
  260. /* move the city & state info to their proper locations */
  261. extract_citystate(dloc,city,state)
  262. char *dloc,*city,*state;
  263. {
  264.    char *tmp;
  265.    
  266.    for(tmp=city;*dloc!='\x09';tmp++,dloc++) *tmp=*dloc;
  267.    *tmp='\0';
  268.    dloc++;
  269.    for(tmp=state;*dloc!='\x0d';tmp++,dloc++) *tmp=*dloc;
  270.    *tmp='\0';
  271. }
  272.  
  273. center_text(text,y)
  274. char *text;
  275. int   y;
  276. {
  277.    putpad(tgoto(CM,(columns-strlen(text))/2,y));
  278.    touts(text);
  279. }
  280.  
  281. /* termcap-aware key input handling code */
  282. int process_key(key)
  283. char key;
  284. {
  285.    int retkey,t;
  286.    
  287.    switch(keyflag)
  288.    {
  289.       case -1:
  290.          retkey=(int)keybuff[keybufpos++];
  291.          if (!(--keybuflen)) keyflag=0;
  292.          break;
  293.       case 0:
  294.          keybuff[0]=key;
  295.          keybufpos=1;
  296.          keybuflen=1;
  297.          t=compare_special();
  298.          if (!t) retkey=(int)key;
  299.          else
  300.          {
  301.             if (t==1)
  302.             {
  303.                retkey=0;
  304.                keyflag=1;
  305.             }
  306.             else retkey=t;
  307.          }
  308.          break;
  309.       case 1:
  310.          keybuff[keybufpos++]=key;
  311.          keybuflen++;
  312.          t=compare_special();
  313.          if (!t)
  314.          {
  315.             keyflag=-1;
  316.             retkey=keybufpos=0;
  317.          }
  318.          else
  319.          {
  320.             if (t==1) retkey=0;
  321.             else
  322.             {
  323.                retkey=t;
  324.                keyflag=0;
  325.             }
  326.          }
  327.          break;
  328.    }
  329.    return(retkey);
  330. }
  331.  
  332. int compare_special()
  333. {
  334.    int t=0;
  335.    
  336.    keybuff[keybufpos]='\0';
  337.    if (!strcmp(keybuff,KU)) t=UP_ARROW;
  338.    if (!strcmp(keybuff,KD)) t=DOWN_ARROW;
  339.    if (!strcmp(keybuff,KL)) t=LEFT_ARROW;
  340.    if (!strcmp(keybuff,KR)) t=RIGHT_ARROW;
  341.    if (!strcmp(keybuff,KB)) t=BACKSPACE;
  342.    if (t) return(t);
  343.    
  344.    if (!strncmp(keybuff,KU,keybuflen)) t=1;
  345.    if (!strncmp(keybuff,KD,keybuflen)) t=1;
  346.    if (!strncmp(keybuff,KL,keybuflen)) t=1;
  347.    if (!strncmp(keybuff,KR,keybuflen)) t=1;
  348.    if (!strncmp(keybuff,KB,keybuflen)) t=1;
  349.    return(t);
  350. }
  351.  
  352. initialize_termcap()
  353. {
  354.    char tcbuf[1024],*term_type,*temp,*ptr;
  355.    
  356.    if ((term_type=getenv("TERM"))==NULL)
  357.    {
  358.       fprintf(stderr,"Environment variable TERM not defined.\n");
  359.       exit(1);
  360.    }
  361.    
  362.    if (tgetent(tcbuf,term_type)<=0)
  363.    {
  364.       fprintf(stderr,"Unknown terminal type '%s'.\n",term_type);
  365.       exit(1);
  366.    }
  367.    
  368.    ptr=tcapbuf;
  369.    if (temp=tgetstr("PC",&ptr)) PC_=*temp;
  370.    CL=tgetstr("cl",&ptr);
  371.    CM=tgetstr("cm",&ptr);
  372.    KU=tgetstr("ku",&ptr);
  373.    KD=tgetstr("kd",&ptr);
  374.    KL=tgetstr("kl",&ptr);
  375.    KR=tgetstr("kr",&ptr);
  376.    KB=tgetstr("kb",&ptr);
  377.    BL=tgetstr("bl",&ptr);
  378.    UP=tgetstr("up",&ptr);
  379.    lines=tgetnum("li");
  380.    columns=tgetnum("co");
  381.    ospeed=0;
  382.    
  383.    if (lines<1 || columns<1)
  384.    {
  385.       fprintf(stderr,"No rows or columns!\n");
  386.       exit(1);
  387.    }
  388.    
  389.    if (!(CL && CM && KL && KR && KB && UP))
  390.    {
  391.       fprintf(stderr,"Incomplete termcap entry.\n");
  392.       fprintf(stderr,"Requires cl, cm, kl, kr, kb, up.\n");
  393.       exit(1);
  394.    }
  395.    
  396.    if (ptr>=&tcapbuf[TCAPSLEN])
  397.    {
  398.       fprintf(stderr,"Terminal description too big!\n");
  399.       exit(1);
  400.    }
  401. }
  402.  
  403. int tputc(c)
  404. char c;
  405. {
  406.    return (write(STDOUT,&c,1));
  407. }
  408.  
  409. touts(s)
  410. char *s;
  411. {
  412.    write(STDOUT,s,strlen(s));
  413. }
  414.  
  415. putpad(s)
  416. char *s;
  417. {
  418.    tputs(s,1,tputc);
  419. }
  420.  
  421. sigtrap(signal)
  422. int signal;
  423. {
  424.    done=1;
  425. }
  426.  
  427. /* The help message: */
  428. print_desc()
  429. {
  430.    fprintf(stderr,"\nZipCode Version 1.0\n");
  431.    fprintf(stderr,"by Joel Mathew Hegberg.\n\n");
  432.    fprintf(stderr,"Syntax:   zc {xxxxx}\n");
  433.    fprintf(stderr,"Function: Application program for looking up city/state information\n");
  434.    fprintf(stderr,"            to a corresponding zip code.\n");
  435.    fprintf(stderr,"            If a zip-code is passed in as an argument (xxxxx),\n");
  436.    fprintf(stderr,"            then ZipCode merely prints out the city/state.\n\n");
  437. }
  438.  
  439.  
  440. /* THE END */
  441.  
  442.