зеркало из https://github.com/github/putty.git
344 строки
6.9 KiB
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;
|
|
}
|
|
}
|