/* vim: set ts=8 sts=4 sw=4 tw=80 noet: */
/*======================================================================
Copyright (C) 2004,2005,2009 Walter Doekes <walter+tthsum@wjd.nu>
This file is part of tthsum.

tthsum 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 3 of the License, or
(at your option) any later version.

tthsum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with tthsum.  If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "escape.h"

#include <stdio.h>

#ifdef USE_TEXTS
#   include "texts.h"
#endif


void strtoctrlesc(char* dest, const char* src) {
    while (*src != '\0') {
	if (0) { /* the optimizer will take care of this */
#define ELIF(ctrl, ch) } else if (*src == ctrl) { *dest++ = '\\'; *dest++ = ch
	ELIF('\a', 'a');
	ELIF('\b', 'b');
	ELIF('\t', 't');
	ELIF('\n', 'n');
	ELIF('\v', 'v');
	ELIF('\f', 'f');
	ELIF('\r', 'r');
	ELIF('\\', '\\');
#undef ELIF
	} else if ((unsigned char)*src < 0x20) {
	    sprintf(dest, "\\x%02hx", (short)*src); /* %hhx is not C90 */
	    dest += 4;
	} else {
	    *dest++ = *src;
	}
	++src;
    }
    *dest = '\0';
}
	
int ctrlesctostr(char* dest, const char* src) {
    while (*src != '\0') {
	if (*src == '\\') {
	    ++src;
	    if (0) { /* the optimizer will take care of this */
#define ELIF(ch, ctrl) } else if (*src == ch) { *dest = ctrl
	    ELIF('a', '\a');
	    ELIF('b', '\b');
	    ELIF('t', '\t');
	    ELIF('n', '\n');
	    ELIF('v', '\v');
	    ELIF('f', '\f');
	    ELIF('r', '\r');
	    ELIF('\\', '\\');
	    } else if (*src == 'x') {
		int i;
		*dest = 0;
		for (i = 0; i < 2; ++i) {
		    ++src;
		    if ((unsigned char)*src >= '0'
			    && (unsigned char)*src <= '9')
			*dest += *src - '0';
		    else if ((unsigned char)*src >= 'A'
			    && (unsigned char)*src <= 'F')
			*dest += *src - 'A' + 10;
		    else if ((unsigned char)*src >= 'a'
			    && (unsigned char)*src <= 'f')
			*dest += *src - 'a' + 10;
		    else {
#ifdef USE_TEXTS
			set_error("ctrlesctostr", ESCAPE_INVALID_ESCAPE);
#endif /* USE_TEXTS */
			return -1;
		    }
		    if (i == 0)
			*dest <<= 4;
		}
	    } else {
#ifdef USE_TEXTS
		set_error("ctrlesctostr", ESCAPE_INVALID_ESCAPE);
#endif /* USE_TEXTS */
		return -1;
	    }
	} else {
	    *dest = *src;
	}
	++dest;
	++src;
    }
    *dest = '\0';
    return 0;
}
