Newer
Older
/* Converts Synchronet Ctrl-A codes into ANSI escape sequences */
/****************************************************************************
* @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 *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* 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 */
#include "git_branch.h"
#include "git_hash.h"
#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)
fprintf(stderr, "\nSynchronet Ctrl-A-Code to ANSI-Terminal-Sequence Conversion Utility %s/%s\n"
, GIT_BRANCH, GIT_HASH);
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;
print_usage(argv[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]);
}
} else if (out == stdout) {
if ((out = fopen(argv[i], "wb")) == NULL) {
perror(argv[i]);
}
#ifdef _WIN32
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 */
if (ch > 0x7f) { /* move cursor right x columns */
int cnt = ch - 0x7f;
if (cnt > 1)
fprintf(out, "%u", cnt);
fputc('C', out);
continue;
switch (toupper(ch)) {
case '/': // Conditional new-line
case 'J':
ANSI;
fprintf(out, "J"); /* clear to EOS */
ANSI;
fprintf(out, "2J"); /* clear screen */
/* fall-through */

rswindell
committed
case '\'':
ANSI;
fprintf(out, "H"); /* home cursor */
break;
case '-':
case '_':
case 'N':
ANSI;
case 'Z': /* Actually a lower-case 'z' */
fputc('\x1a', out); /* Ctrl-Z (substitute) char */
break;
if (!strip)
fprintf(out, "\1%c", ch);
break;
}