putty/mkres.c

344 строки
6.9 KiB
C

/*
*
* Commands ...
*
* INIT(...) : Set configs. (rowstep, totwidth, stdheight, stdwidth)
* SPOS(V,H) : Set current position.
*
* SCOL : Standard column, for a single column, increment position
* NEXT(V,H) : increment postion by standard + (V,H)
* COL(K,N) : X,Y position for col K of N (default 1of [same as last])
* SS : Standard size of last COL (using number of cols).
* ADJ(V,H) : Adjust next COL or SCOL by (V,H)
*
* CURX(H) : Current Xpos+H
* CURY(V) : Current Ypos+V
*
*/
#include <stdio.h>
FILE * ifd;
FILE * ofd;
char wordbuf[256];
#define T_INIT 100 /* Init the style of the values */
#define T_SPOS 101 /* Set the current position */
#define T_SCOL 102 /* Standard column COL(1,1), SS NEXT */
#define T_NEXT 103 /* Next line */
#define T_COL 104 /* Multi-column */
#define T_SS 105 /* Standard Size */
#define T_ADJ 106 /* Adjust next COL/SCOL */
#define T_GRID 107 /* */
#define T_GAP 108 /* */
#define T_CURX 120 /* Current X + offset */
#define T_CURY 121 /* Current Y + offset */
#define T_SAVEPOSN 122 /* Save current status */
#define T_RESTOREPOSN 123 /* Restore current status */
struct keys {
char * name;
int token;
} keywords[] = {
{"INIT", T_INIT, },
{"SPOS", T_SPOS, },
{"SCOL", T_SCOL, },
{"NEXT", T_NEXT, },
{"COL", T_COL, },
{"SS", T_SS, },
{"ADJ", T_ADJ, },
{"GRID", T_GRID, },
{"GAP", T_GAP, },
{"CURX", T_CURX, },
{"CURY", T_CURY, },
{"SAVEPOSN", T_SAVEPOSN, },
{"RESTOREPOSN", T_RESTOREPOSN, },
{0,0}
};
struct statbuf {
int token;
int curx;
int cury;
int cols;
int con_width;
int con_height;
int row_step;
int tot_width;
int gutter;
int vadjust;
int hadjust;
}
status, saved_status;
int ar_count, ar_val[10];
main(argc, argv)
int argc;
char ** argv;
{
int ch;
ifd = stdin; ofd = stdout;
while(!feof(ifd))
{
if (ferror(ifd))
{
fprintf(stderr, "Error reading input file\n");
exit(1);
}
if (readword() < 0) break;
if (check_keys() < 0)
{
fprintf(ofd, "%s", wordbuf);
continue;
}
/* To get here we have found one of our keywords, some words will
* be followed by an argument.
*/
ar_count = 0;
while((ch = getc(ifd)) != EOF && isspace(ch) && ch != '\n')
putc(ch, ofd);
if (ch == '(' )
{
for(;;)
{
ar_val[ar_count++] = get_number();
while((ch=getc(ifd)) != EOF && isspace(ch)) ;
if (ch != ',') break;
}
if (ch == EOF) break;
}
else
ungetc(ch, ifd);
/* Ok got args, now doit */
execute_command();
}
exit(0);
}
/* This is the lexer - not using lex(1) because this will have to
* compile under windows.
*/
int readword()
{
int ch;
char *wp;
try_again:; /* This is for "too big" words and strings. */
wp=wordbuf;
/* Find a word ... */
while((ch=getc(ifd)) != EOF && !isalpha(ch) && ch != '"')
putc(ch, ofd);
if (ch == '"')
{
putc(ch, ofd);
while((ch=getc(ifd)) != EOF && ch != '"')
putc(ch, ofd);
if (ch != EOF)
putc(ch, ofd);
goto try_again;
}
if (ch == EOF) return -1;
do
{
if (wp>=wordbuf+sizeof(wordbuf)-2)
{
*wp = 0;
fprintf(ofd, "%s", wordbuf);
while(ch!=EOF && isalpha(ch))
{
putc(ch, ofd);
ch=getc(ifd);
}
ungetc(ch, ifd);
goto try_again;
}
*wp++ = ch;
ch = getc(ifd);
}
while(ch != EOF && (isalnum(ch) || ch == '_'));
*wp = 0;
ungetc(ch, ifd);
return wp-wordbuf;
}
int
get_number()
{
int ch;
int sign = 0;
int value = 0;
while((ch=getc(ifd)) != EOF && isspace(ch)) ;
if( ch == '+' ) { sign=1; ch=getc(ifd); }
else if( ch == '-' ) { sign=-1; ch=getc(ifd); }
while(ch>='0' && ch<='9')
{
value = value * 10 + ch - '0';
ch = getc(ifd);
}
ungetc(ch, ifd);
if (sign < 0) value = -value;
return value;
}
check_keys()
{
struct keys *p;
for(p=keywords; p->name; p++)
{
if (strcmp(wordbuf, p->name) == 0 )
{
status.token = p->token;
return p->token;
}
}
return -1;
}
execute_command()
{
if (status.cols < 1) status.cols = 1;
switch(status.token)
{
case T_INIT:
if (ar_count > 0) status.row_step = ar_val[0];
if (ar_count > 1) status.tot_width = ar_val[1];
if (ar_count > 2) status.con_height = ar_val[2];
else status.con_height = status.row_step;
if (ar_count > 3) status.con_width = ar_val[3];
else status.con_width = status.tot_width;
status.gutter = ( status.tot_width - status.con_width ) /2;
break;
case T_SPOS:
status.cury = status.curx = 0;
if (ar_count > 0) status.cury = ar_val[0];
if (ar_count > 1) status.curx = ar_val[1];
break;
case T_SCOL:
fprintf(ofd, "%d, %d", status.curx + status.hadjust,
status.cury + status.vadjust);
status.hadjust = status.vadjust = 0;
fprintf(ofd, ", %d, %d", status.con_width, status.con_height);
status.cury += status.row_step;
if (ar_count > 0) status.cury += ar_val[0];
if (ar_count > 1) status.curx += ar_val[1];
break;
case T_NEXT:
status.cury += status.row_step;
if (ar_count > 0) status.cury += ar_val[0];
if (ar_count > 1) status.curx += ar_val[1];
break;
case T_COL:
{
int curcol;
int col_pos;
if (ar_count > 0) curcol = ar_val[0]; else curcol = 1;
if (ar_count > 1) status.cols = ar_val[1];
col_pos = (status.con_width+status.gutter) *(curcol-1) /status.cols;
fprintf(ofd, "%d, %d",
status.curx + status.hadjust + col_pos,
status.cury + status.vadjust);
status.hadjust = status.vadjust = 0;
}
break;
case T_SS:
{
int wm = 1, hm=1;
int width;
if (ar_count > 0) wm = ar_val[0];
if (ar_count > 1) hm = ar_val[1];
width = (status.con_width+status.gutter) / status.cols;
width *= wm;
width -= status.gutter;
fprintf(ofd, "%d, %d", width, hm*status.con_height);
}
break;
case T_ADJ:
if (ar_count > 0) status.vadjust = ar_val[0];
if (ar_count > 1) status.hadjust = ar_val[0];
break;
case T_GRID:
if (ar_count > 0) status.cols = ar_val[0];
else status.cols = 1;
if (ar_count > 1) status.con_height = ar_val[1];
if (ar_count > 2) status.row_step = ar_val[2];
break;
case T_GAP:
if (ar_count > 0) status.cury += ar_val[0];
else status.cury += 2;
break;
case T_CURX:
if (ar_count>0)
fprintf(ofd, "%d", status.curx+ar_val[0]);
else
fprintf(ofd, "%d", status.curx);
break;
case T_CURY:
if (ar_count>0)
fprintf(ofd, "%d", status.cury+ar_val[0]);
else
fprintf(ofd, "%d", status.cury);
break;
case T_SAVEPOSN:
saved_status = status;
break;
case T_RESTOREPOSN:
status = saved_status;
break;
}
}