#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
+
+#include "util.h"
+
+int fromHex(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c-'0';
+ if (c >= 'a' && c <= 'f')
+ return c-'a'+10;
+ if (c >= 'A' && c <= 'F')
+ return c-'A'+10;
+ return -1;
+}
+
+char *escape_char(char c, char *buf, bool str)
+{
+ buf = buf == NULL ? safe_malloc(10) : buf;
+ switch (c) {
+ case '\0': strcpy(buf, "\\0"); break;
+ case '\a': strcpy(buf, "\\a"); break;
+ case '\b': strcpy(buf, "\\b"); break;
+ case '\t': strcpy(buf, "\\t"); break;
+ case '\n': strcpy(buf, "\\n"); break;
+ case '\v': strcpy(buf, "\\v"); break;
+ case '\f': strcpy(buf, "\\f"); break;
+ case '\r': strcpy(buf, "\\r"); break;
+ case '\\': strcpy(buf, "\\\\"); break;
+ case '\'': strcpy(buf, str ? "'" : "\\'"); break;
+ case '"': strcpy(buf, str ? "\\\"" : "\""); break;
+ default:
+ if (c >= ' ' && c < 127)
+ sprintf(buf, "%c", c);
+ else
+ sprintf(buf, "\\x%02x", (unsigned char)c);
+ break;
+ }
+ return buf;
+}
+
+bool isodigit(char c)
+{
+ return c >= '0' && c <= '7';
+}
+
+int fromOctal(char c)
+{
+ if (isodigit(c))
+ return c-'0';
+ return -1;
+}
+
+char *unescape_char(char *c)
+{
+ if (c[0] == '\\') {
+ if (c[1] == 'x' && isxdigit(c[2])) {
+ //two hex
+ if (isxdigit(c[3])) {
+ c[3] = (fromHex(c[2])*16)+fromHex(c[3]);
+ c+=2;
+ //one hex
+ } else {
+ c[2] = fromHex(c[2]);
+ c++;
+ }
+ } else if (c[1] == '0' && isodigit(c[2])) {
+ if (isodigit(c[3])) {
+ //three octal
+ if (isodigit(c[4])) {
+ c[4] = fromOctal(c[2])*64
+ +fromOctal(c[3])*8
+ +fromOctal(c[4]);
+ c+=2;
+ //two octal
+ } else {
+ c[3] = fromOctal(c[2])*8
+ +fromOctal(c[3]);
+ c+=2;
+ }
+ // one octal
+ } else {
+ c[2] = fromOctal(c[2]);
+ c++;
+ }
+ } else {
+ switch (c[1]) {
+ case '0': c[1] = '\0'; break;
+ case '\'': c[1] = '\''; break;
+ case '\\': c[1] = '\\'; break;
+ case '"': c[1] = '"'; break;
+ case 'a': c[1] = '\a'; break;
+ case 'b': c[1] = '\b'; break;
+ case 't': c[1] = '\t'; break;
+ case 'v': c[1] = '\v'; break;
+ case 'f': c[1] = '\f'; break;
+ case 'r': c[1] = '\r'; break;
+ }
+ }
+ c++;
+ }
+ return c;
+}
+
+char *trimquotes(char *c)
+{
+ char *r = c+1;
+ r[strlen(r)-1] = '\0';
+ return r;
+}
void pdie(const char *msg)
{
void *safe_strdup(const char *c)
{
- char *res = strdup(c);
+ size_t nchar = strlen(c);
+ char *res = malloc((nchar+1)*sizeof(char));
if (res == NULL)
pdie("strdup");
+ memcpy(res, c, nchar+1);
return res;
}
+
+FILE *safe_fopen(const char *path, const char *mode)
+{
+ FILE *res = fopen(path, mode);
+ if (res == NULL)
+ pdie("fopen");
+ return res;
+}
+
+void safe_fclose(FILE *file)
+{
+ if (fclose(file) == -1)
+ pdie("fclose");
+}