home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HAM Radio 1
/
HamRadio.cdr
/
tech
/
pcbsrcs2
/
pcbpsplt.c
< prev
next >
Wrap
Text File
|
1991-02-07
|
8KB
|
332 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINELEN 1024
char *gettoken();
char *getfpn();
double cvtfpn();
#define X 1 /* offset codes for psoutp */
#define Y 2
#define R 0
int linenum;
char buffer[ LINELEN ], *start, *endwd, delim;
char retrnbuf[ LINELEN ];
double offsx = 10.0, offsy = 10.0; /* init to shift off edge of raster */
double sizex = 500.0, sizey = 720.0; /* size of page in x and y */
void process( void );
void prolog( void );
void epilog( void );
int catfile( char * );
void geteol( void );
void do_dim( void );
void do_line( void );
void do_circle( void );
void fixup( char * );
void syntax( char *, char * );
void psoutp( char *, char );
int islegal( char );
void main()
{
prolog(); /* look for header file */
printf( "\n%%%% PCBPSPLT.EXE: version 1.0, written by Dave Schmidt WB7RDI\n" );
printf( "%%%% This program is public domain. Author and author's employer bear\n" );
printf( "%%%% NO responsibility for its completeness, correctness, or\n" );
printf( "%%%% usefulness. So there.\n" );
process(); /* handle the actual input from stdin */
epilog(); /* look for trailer file */
exit( 0 ); /* end program normally */
}
void process()
{
char *tok;
for(;;)
{
if( (tok = gettoken()) == NULL )
return; /* normal place to get an EOF */
if( !*tok )
continue; /* ok to get blank line, also */
if( *tok == '#' || *tok == ';' || *tok == '%' || *tok == '/' )
{
/* ignore rest of line, as it is a comment */
geteol();
continue;
}
/* now, test for expected first words in line */
if( !strcmp( tok, "dimension" ))
do_dim();
else if( !strcmp( tok, "line" ))
do_line();
else if( !strcmp( tok, "circle" ))
do_circle();
else
syntax( tok, "unknown keyword" );
geteol();
}
}
void geteol()
{
/* keep reading tokens till end of line is found */
/* actually, just short circuit gettoken's input buffer */
start = NULL;
}
char *getfpn()
{
/* get a floating point number string from the next token. If token is
* non-numeric, return NULL as an error indication.
*/
char *tok, *c;
if( (tok = gettoken()) == NULL ) /* end of file is illegal */
{
syntax( tok, "unexpected EOF. Expected number." );
return( 0 );
}
if( !*tok ) /* end of line is illegal */
{
syntax( tok, "unexpected end of line. Expected number." );
return( 0 );
}
for( c = tok; *c; c++ )
{
if( ( *c > '9' || *c < '0' ) && *c != '.' )
{
syntax( tok, "bad numeric character." );
return( NULL );
}
}
return( tok ); /* successful conversion */
}
void syntax( token, reason )
char *token, *reason;
{
fprintf( stderr, "syntax error at line %d: %s\n", linenum, buffer );
fprintf( stderr, "\ttoken '%s':%s\n", token, reason );
}
void do_dim()
{
/* dimension information is simply the size of the board.
* we need to get an x and y value, which are the maximum X and Y
* values to be expected on the board
*/
char *p;
double shiftx, shifty;
/* attempt to shift the board drawing to the middle of the page.
* adjust offsx,offsy to shift the drawing up and right by half
* a page - half the size of the board. Page dimensions are in sizex,sizey.
*/
if( !(p = getfpn()) )
return;
shiftx = cvtfpn( p ); /* get max x value */
if( !(p = getfpn()) )
return;
shifty = cvtfpn( p ); /* get max y value */
offsx += (sizex - shiftx) / 2.0; /* add half page minus half */
offsy += (sizey - shifty) / 2.0; /* of the board size to origin */
printf( "%%%% Board dimensions: %g %g. new origin at %g %g\n",
shiftx, shifty, offsx, offsy );
}
void do_line()
{
/* line command gets two endpoints, and just needs to pass them thru. */
char *p;
printf( " newpath " );
if( !(p = getfpn()) )
return;
psoutp( p, X ); /* print first x value */
if( !(p = getfpn()) )
return;
psoutp( p, Y ); /* print first y value */
printf( " moveto " );
if( !(p = getfpn()) )
return;
psoutp( p, X ); /* print second x value */
if( !(p = getfpn()) )
return;
psoutp( p, Y ); /* print second y value */
printf( " lineto closepath stroke\n" );
}
void do_circle()
{
/* circle command gets x,y center followed by radius */
char *p;
printf( " newpath " );
if( !(p = getfpn()) )
return;
psoutp( p, X ); /* print center x value */
if( !(p = getfpn()) )
return;
psoutp( p, Y ); /* print center y value */
if( !(p = getfpn()) )
return;
psoutp( p, R ); /* print radius value */
printf( " 0 360 arc stroke closepath\n" );
}
void psoutp( p, offscode )
char *p;
char offscode;
{
/* print the value in the string in postscript form. Rescale to convert
* mils to points. (1000 mils/inch, 72 points/inch)
*/
if( offscode == X )
printf( " %g ", cvtfpn( p ) + offsx );
else if( offscode == Y )
printf( " %g ", cvtfpn( p ) + offsy );
else
printf( " %g ", cvtfpn( p ));
}
double cvtfpn( p )
char *p;
{
/* convert string pointed to by p into postscript-scaled float */
double atof();
return( ( atof( p ) / 1000.0 ) * 72.0 );
}
char *gettoken()
{
/* this function returns the next item from stdin as a null terminated word.
* the legal characters in any string are defined in the islegal() function.
* Special values returned are: NULL for end of file, and a zero length string
* for end of line. Callers may find end of line in this manner.
*/
/* only leave this loop by finding EOF (return NULL then),
* by finding a nonzero length word to return to the caller,
* or, on end of line, return a zero length word.
*/
for(;;)
{
if( !start || !*start )
{
if( fgets( buffer, LINELEN, stdin ) == NULL )
return( NULL );
linenum++;
fixup( buffer );
start = buffer;
}
/* we have a line, remove any leading whitespace */
while( *start <= ' ' )
{ /* detected end of line */
if( !*start )
{
start = NULL;
*retrnbuf = 0;
return( retrnbuf );
}
start++;
}
/* found beginning. look for word delimiter */
for( endwd = start; islegal( *endwd ); endwd++ );
/* null terminate the word */
delim = *endwd;
*endwd = 0;
/* copy word into retrnbuf and return ptr to it */
strcpy( retrnbuf, start );
*endwd = delim;
start = endwd;
return( retrnbuf );
}
}
void fixup( s )
char *s;
{
/* remove undesirable characters from input string */
char *kills = "(),\t\f\n", *p;
while( *s )
{
for( p = kills; *p; p++ )
{
if( *p == *s )
{
*s = ' ';
break;
}
}
if( *s >= 'A' && *s <= 'Z' ) /* force lower case */
*s += 0x20;
s++;
}
}
int islegal( ch )
char ch;
{
/* return true if character is legal in a token */
char *legals = "0123456789abcdefghijklmnopqrstuvwxyz/#%;.";
char *s;
for( s = legals; *s; s++ )
if( *s == ch )
return( 1 );
return( 0 );
}
void prolog()
{
/* try to prepend the prologue file */
if( !catfile( "pcbpsplt.pro" ) )
printf( "%%!\n%%%% pcbpsplt.pro not found.\n" );
}
void epilog()
{
/* try to append the epilogue file */
if( !catfile( "pcbpsplt.epi" ) )
printf( "%%%% pcbpsplt.epi not found.\nshowpage\n" );
}
int catfile( fn )
char *fn;
{
/* look for the specified file, and if it exists, read it and copy to stdout.
* If not found, return zero.
*/
FILE *f;
int ch;
if( (f = fopen( fn, "r" )) == NULL )
return( 0 );
while( (ch = getc( f )) != EOF )
putchar( (char)ch );
fclose( f );
return( 1 );
}