home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1 / HamRadio.cdr / tech / pcbsrcs2 / pcbpsplt.c < prev    next >
Text File  |  1991-02-07  |  8KB  |  332 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define    LINELEN    1024
  6.  
  7. char    *gettoken();
  8. char    *getfpn();
  9. double    cvtfpn();
  10.  
  11. #define    X    1    /* offset codes for psoutp */
  12. #define    Y    2
  13. #define    R    0
  14.  
  15. int    linenum;
  16. char    buffer[ LINELEN ], *start, *endwd, delim;
  17. char    retrnbuf[ LINELEN ];
  18. double    offsx = 10.0, offsy = 10.0;    /* init to shift off edge of raster */
  19. double    sizex = 500.0, sizey = 720.0;    /* size of page in x and y */
  20.  
  21. void process( void );
  22. void prolog( void );
  23. void epilog( void );
  24. int catfile( char * );
  25. void geteol( void );
  26. void do_dim( void );
  27. void do_line( void );
  28. void do_circle( void );
  29. void fixup( char * );
  30. void syntax( char *, char * );
  31. void psoutp( char *, char );
  32. int islegal( char );
  33.  
  34. void main()
  35. {
  36.     prolog();    /* look for header file */
  37.  
  38.     printf( "\n%%%% PCBPSPLT.EXE: version 1.0, written by Dave Schmidt WB7RDI\n" );
  39.     printf( "%%%% This program is public domain. Author and author's employer bear\n" );
  40.     printf( "%%%% NO responsibility for its completeness, correctness, or\n" );
  41.     printf( "%%%% usefulness. So there.\n" );
  42.  
  43.     process();    /* handle the actual input from stdin */
  44.     epilog();    /* look for trailer file */
  45.     exit( 0 );    /* end program normally */
  46. }
  47.  
  48. void process()
  49. {
  50.     char    *tok;
  51.  
  52.     for(;;)
  53.     {
  54.         if( (tok = gettoken()) == NULL )
  55.             return;        /* normal place to get an EOF */
  56.  
  57.         if( !*tok )
  58.             continue;    /* ok to get blank line, also */
  59.  
  60.         if( *tok == '#' || *tok == ';' || *tok == '%' || *tok == '/' )
  61.         {
  62.             /* ignore rest of line, as it is a comment */
  63.             geteol();
  64.             continue;
  65.         }
  66.  
  67.         /* now, test for expected first words in line */
  68.         if( !strcmp( tok, "dimension" ))
  69.             do_dim();
  70.         else if( !strcmp( tok, "line" ))
  71.             do_line();
  72.         else if( !strcmp( tok, "circle" ))
  73.             do_circle();
  74.         else
  75.             syntax( tok, "unknown keyword" );
  76.         geteol();
  77.     }
  78. }
  79. void geteol()
  80. {
  81.  /* keep reading tokens till end of line is found */
  82.  /* actually, just short circuit gettoken's input buffer */
  83.  
  84.     start = NULL;
  85. }
  86. char *getfpn()
  87. {
  88.  /* get a floating point number string from the next token. If token is
  89.   * non-numeric, return NULL as an error indication.
  90.   */
  91.     char    *tok, *c;
  92.  
  93.     if( (tok = gettoken()) == NULL )    /* end of file is illegal */
  94.     {
  95.         syntax( tok, "unexpected EOF. Expected number." );
  96.         return( 0 );
  97.     }
  98.     if( !*tok )        /* end of line is illegal */
  99.     {
  100.         syntax( tok, "unexpected end of line. Expected number." );
  101.         return( 0 );
  102.     }
  103.     for( c = tok; *c; c++ )
  104.     {
  105.         if( ( *c > '9' || *c < '0' ) && *c != '.' )
  106.         {
  107.             syntax( tok, "bad numeric character." );
  108.             return( NULL );
  109.         }
  110.     }
  111.     return( tok );        /* successful conversion */
  112. }
  113. void syntax( token, reason )
  114. char    *token, *reason;
  115. {
  116.     fprintf( stderr, "syntax error at line %d: %s\n", linenum, buffer );
  117.     fprintf( stderr, "\ttoken '%s':%s\n", token, reason );
  118. }
  119. void do_dim()
  120. {
  121.  /* dimension information is simply the size of the board.
  122.   * we need to get an x and y value, which are the maximum X and Y
  123.   * values to be expected on the board
  124.   */
  125.     char    *p;
  126.     double    shiftx, shifty;
  127.  
  128.  /* attempt to shift the board drawing to the middle of the page.
  129.   * adjust offsx,offsy to shift the drawing up and right by half
  130.   * a page - half the size of the board. Page dimensions are in sizex,sizey.
  131.   */
  132.  
  133.     if( !(p = getfpn()) )
  134.         return;
  135.     shiftx = cvtfpn( p );    /* get max x value */
  136.  
  137.     if( !(p = getfpn()) )
  138.         return;
  139.     shifty = cvtfpn( p );    /* get max y value */
  140.  
  141.     offsx += (sizex - shiftx) / 2.0;    /* add half page minus half */
  142.     offsy += (sizey - shifty) / 2.0;    /* of the board size to origin */
  143.  
  144.     printf( "%%%% Board dimensions: %g %g. new origin at %g %g\n",
  145.         shiftx, shifty, offsx, offsy );
  146. }
  147. void do_line()
  148. {
  149.  /* line command gets two endpoints, and just needs to pass them thru. */
  150.     char    *p;
  151.  
  152.     printf( " newpath " );
  153.     if( !(p = getfpn()) )
  154.         return;
  155.     psoutp( p, X );    /* print first x value */
  156.  
  157.     if( !(p = getfpn()) )
  158.         return;
  159.     psoutp( p, Y );    /* print first y value */
  160.  
  161.     printf( " moveto " );
  162.  
  163.     if( !(p = getfpn()) )
  164.         return;
  165.     psoutp( p, X );    /* print second x value */
  166.  
  167.     if( !(p = getfpn()) )
  168.         return;
  169.     psoutp( p, Y );    /* print second y value */
  170.     
  171.     printf( " lineto closepath stroke\n" );
  172. }
  173. void do_circle()
  174. {
  175.  /* circle command gets x,y center followed by radius */
  176.     char    *p;
  177.  
  178.     printf( " newpath " );
  179.  
  180.     if( !(p = getfpn()) )
  181.         return;
  182.     psoutp( p, X );    /* print center x value */
  183.  
  184.     if( !(p = getfpn()) )
  185.         return;
  186.     psoutp( p, Y );    /* print center y value */
  187.  
  188.     if( !(p = getfpn()) )
  189.         return;
  190.     psoutp( p, R );    /* print radius value */
  191.  
  192.     printf( " 0 360 arc stroke closepath\n" );
  193. }
  194.  
  195. void psoutp( p, offscode )
  196. char    *p;
  197. char    offscode;
  198. {
  199.  /* print the value in the string in postscript form. Rescale to convert
  200.   * mils to points. (1000 mils/inch, 72 points/inch)
  201.   */
  202.     if( offscode == X )
  203.         printf( " %g ", cvtfpn( p ) + offsx );
  204.     else if( offscode == Y )
  205.         printf( " %g ", cvtfpn( p ) + offsy );
  206.     else
  207.         printf( " %g ", cvtfpn( p ));
  208. }
  209.  
  210. double cvtfpn( p )
  211. char    *p;
  212. {
  213.  /* convert string pointed to by p into postscript-scaled float */
  214.     double    atof();
  215.  
  216.     return( ( atof( p ) / 1000.0 ) * 72.0 );
  217. }
  218.  
  219. char    *gettoken()
  220. {
  221.  /* this function returns the next item from stdin as a null terminated word.
  222.   * the legal characters in any string are defined in the islegal() function.
  223.   * Special values returned are: NULL for end of file, and a zero length string
  224.   * for end of line. Callers may find end of line in this manner.
  225.   */
  226.  
  227.     /* only leave this loop by finding EOF (return NULL then),
  228.      * by finding a nonzero length word to return to the caller,
  229.      * or, on end of line, return a zero length word.
  230.      */
  231.  
  232.     for(;;)
  233.     {
  234.         if( !start || !*start )
  235.         {
  236.             if( fgets( buffer, LINELEN, stdin ) == NULL )
  237.                 return( NULL );
  238.             linenum++;
  239.             fixup( buffer );
  240.             start = buffer;
  241.         }
  242.  
  243.         /* we have a line, remove any leading whitespace */
  244.         while( *start <= ' ' )
  245.         {    /* detected end of line */
  246.             if( !*start )
  247.             {
  248.                 start = NULL;
  249.                 *retrnbuf = 0;
  250.                 return( retrnbuf );
  251.             }
  252.             start++;
  253.         }
  254.  
  255.         /* found beginning. look for word delimiter */
  256.         for( endwd = start; islegal( *endwd ); endwd++ );
  257.  
  258.         /* null terminate the word */
  259.         delim = *endwd;
  260.         *endwd = 0;
  261.  
  262.         /* copy word into retrnbuf and return ptr to it */
  263.         strcpy( retrnbuf, start );
  264.         *endwd = delim;
  265.         start = endwd;
  266.  
  267.         return( retrnbuf );
  268.     }
  269. }
  270. void fixup( s )
  271. char    *s;
  272. {
  273.     /* remove undesirable characters from input string */
  274.     char    *kills = "(),\t\f\n", *p;
  275.  
  276.     while( *s )
  277.     {
  278.         for( p = kills; *p; p++ )
  279.         {
  280.             if( *p == *s )
  281.             {
  282.                 *s = ' ';
  283.                 break;
  284.             }
  285.         }
  286.         if( *s >= 'A' && *s <= 'Z' )    /* force lower case */
  287.             *s += 0x20;
  288.         s++;
  289.     }
  290. }
  291. int islegal( ch )
  292. char    ch;
  293. {
  294.     /* return true if character is legal in a token */
  295.     char    *legals = "0123456789abcdefghijklmnopqrstuvwxyz/#%;.";
  296.     char    *s;
  297.  
  298.     for( s = legals; *s; s++ )
  299.         if( *s == ch )
  300.             return( 1 );
  301.     return( 0 );
  302. }
  303. void prolog()
  304. {
  305.  /* try to prepend the prologue file */
  306.     if( !catfile( "pcbpsplt.pro" ) )
  307.         printf( "%%!\n%%%% pcbpsplt.pro not found.\n" );
  308. }
  309. void epilog()
  310. {
  311.  /* try to append the epilogue file */
  312.     if( !catfile( "pcbpsplt.epi" ) )
  313.         printf( "%%%% pcbpsplt.epi not found.\nshowpage\n" );
  314. }
  315. int catfile( fn )
  316. char    *fn;
  317. {
  318.  /* look for the specified file, and if it exists, read it and copy to stdout.
  319.   * If not found, return zero.
  320.   */
  321.     FILE    *f;
  322.     int    ch;
  323.  
  324.     if( (f = fopen( fn, "r" )) == NULL )
  325.         return( 0 );
  326.  
  327.     while( (ch = getc( f )) != EOF )
  328.         putchar( (char)ch );
  329.     fclose( f );
  330.     return( 1 );
  331. }
  332.