/* lips3 binary を lips3 code txt に落す
 * 09/23 1996
 * 08/19 1998
 * 07/01 2003
 * shige
 * lipsb2t.c
 */
/* gcc -o lipsb2t lipsb2t.c
 * 使用法: lipsb2t [LIPS data file] (> file.txt)
 */
/* 1) 元々は下のメールの物。
 * 2) CSI, DCS, ST, IS1(?), IS2 などにも対応。
 *
 * 08/19 1998
 * 3) filename == "-" -> stdin
 * 4) vector mode の parameter の部分をちゃんとしたいが、それをやりだす
 *    と長くなるので今はやめておく。
 *
 * 07/01 2003
 * 5) 少しコメント部分をいじって <stdlib.h> を追加しただけ。
 * 6) 本当は、出力に各コマンドの意味も書けるようにしたいが、面倒なので
 *    とりあえずパス。
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ESC (0x1b)
#define DCS (0x90)
#define CSI (0x9b)
#define ST (0x9c)
#define DCS2 (0x50)
#define CSI2 (0x5b)
#define ST2 (0x5c)
#define IS1 (0x1f)
#define IS2 (0x1e)
#define SP (0x20)
#define BEL (0x07)
#define special(c) ((c)==DCS || (c)==CSI || (c)==ST || (c)==IS1 || (c)==IS2 \
		    || (c)==SP || (c)==BEL)
#define msk(c) ((unsigned char)(c))
#define myisascii(c) (msk(c)>=0x20 && msk(c)<=0x7e)

int main(int argc,char *argv[])
{
    int c,c1;
    FILE *infile;
    int unget=0,inDCS=0;

    if(argc<2) return 0;
    if(strcmp(argv[1],"-")==0) infile=stdin;
    else if((infile=fopen(argv[1],"r"))==NULL) return 0;
    c=fgetc(infile);
    while(c!=EOF){
	if(c==ESC){
	    c1=fgetc(infile);
	    switch(c1){
	    case EOF: return 0;
	    case DCS2: printf("\nDCS "); inDCS=1; break;
	    case CSI2: printf("\nCSI "); break;
	    case ST2:
		if(inDCS){ printf(" ST\n"); inDCS=0; }
		else  printf ("\nESC %c",msk(c1));
		break;
	    default:
		printf("\nESC "); unget=1;
		break;
	    }
	}
	else
	if(special(c)){
	    switch(c){
	    case DCS: printf("\nDCS "); inDCS=1; break;
	    case CSI: printf("\nCSI "); break;
	    case ST: printf(" ST\n"); inDCS=0; break;
	    case IS1: printf(" IS1\n"); break;
	    case IS2: printf(" IS2\n"); break;
	    case SP: printf(" SP "); break;
	    case BEL: printf(" BEL "); break;
	    }
	}
	else if(!myisascii(c)) printf(" %XH",msk(c));
	else putchar(msk(c));

	if(unget){ c=c1; unget=0; }
	else c=fgetc(infile);
    }
    putchar('\n');
    return 0;
}

