/* asc2ans.c */ /* Converts Synchronet Ctrl-A codes into ANSI escape sequences */ /* $Id$ */ /**************************************************************************** * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * * Copyright Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * See the GNU General Public License for more details: gpl.txt or * * http://www.fsf.org/copyleft/gpl.html * * * * Anonymous FTP access to the most recent released source is available at * * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * * * * Anonymous CVS access to the development source and modification history * * is available at cvs.synchro.net:/cvsroot/sbbs, example: * * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * * (just hit return, no password is necessary) * * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * * * * For Synchronet coding style and modification guidelines, see * * http://www.synchro.net/source.html * * * * You are encouraged to submit any modifications (preferably in Unix diff * * format) via e-mail to mods@synchro.net * * * * Note: If this box doesn't appear square, then you need to fix your tabs. * ****************************************************************************/ #include <stdio.h> #include <ctype.h> /* toupper */ #include <string.h> /* strcmp */ #ifdef _WIN32 #include <Windows.h> /* SetConsoleMode */ #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #endif #endif #define CTRL_A '\1' #define ANSI fprintf(out,"\x1b[") static void print_usage(const char* prog) { char revision[16]; sscanf("$Revision$", "%*s %s", revision); fprintf(stderr,"\nSynchronet Ctrl-A-Code to ANSI-Terminal-Sequence Conversion Utility v%s\n",revision); fprintf(stderr,"\nusage: %s infile.asc [outfile.ans] [[option] [...]]\n",prog); fprintf(stderr,"\noptions:\n\n"); fprintf(stderr,"-strip strip Ctrl-A codes without ANSI equivalent, e.g. pause, delay\n"); } int main(int argc, char **argv) { int ch; int i; int strip=0; FILE* in=stdin; FILE* out=stdout; if(argc<2) { print_usage(argv[0]); return(0); } for(i=1; i<argc; i++) { if(argv[i][0]=='-') { if(strcmp(argv[i], "-strip") == 0) strip = 1; else { print_usage(argv[0]); return 0; } } else if(in==stdin) { if((in=fopen(argv[i],"rb"))==NULL) { perror(argv[i]); return(1); } } else if(out==stdout) { if((out=fopen(argv[i],"wb"))==NULL) { perror(argv[i]); return(1); } } } #ifdef _WIN32 if(out == stdout) { DWORD conmode = 0; if(GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &conmode)) { SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), conmode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); } } #endif while((ch=fgetc(in))!=EOF) { if(ch==CTRL_A) { /* ctrl-a */ ch=fgetc(in); if(ch==EOF || ch=='Z') /* EOF */ break; if(ch>0x7f) { /* move cursor right x columns */ int cnt=ch-0x7f; ANSI; if(cnt>1) fprintf(out,"%u",cnt); fputc('C',out); continue; } switch(toupper(ch)) { case 'A': fputc('\1',out); break; case '<': fputc('\b',out); break; case '>': ANSI; fputc('K',out); break; case '[': fputc('\r',out); break; case ']': fputc('\n',out); break; case 'J': ANSI; fprintf(out,"J"); /* clear to EOS */ break; case 'L': ANSI; fprintf(out,"2J"); /* clear screen */ /* fall-through */ case '`': ANSI; fprintf(out,"H"); /* home cursor */ break; case '-': case '_': case 'N': ANSI; fprintf(out,"0m"); break; case 'H': ANSI; fprintf(out,"1m"); break; case 'I': ANSI; fprintf(out,"5m"); break; case 'K': ANSI; fprintf(out,"30m"); break; case 'R': ANSI; fprintf(out,"31m"); break; case 'G': ANSI; fprintf(out,"32m"); break; case 'Y': ANSI; fprintf(out,"33m"); break; case 'B': ANSI; fprintf(out,"34m"); break; case 'M': ANSI; fprintf(out,"35m"); break; case 'C': ANSI; fprintf(out,"36m"); break; case 'W': ANSI; fprintf(out,"37m"); break; case '0': ANSI; fprintf(out,"40m"); break; case '1': ANSI; fprintf(out,"41m"); break; case '2': ANSI; fprintf(out,"42m"); break; case '3': ANSI; fprintf(out,"43m"); break; case '4': ANSI; fprintf(out,"44m"); break; case '5': ANSI; fprintf(out,"45m"); break; case '6': ANSI; fprintf(out,"46m"); break; case '7': ANSI; fprintf(out,"47m"); break; case 'Z': /* Actually a lower-case 'z' */ fputc('\x1a',out); /* Ctrl-Z (substitute) char */ break; default: if(!strip) fprintf(out,"\1%c",ch); break; } } else fputc(ch,out); } return(0); }