00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define _GNU_SOURCE
00026 #include <stdlib.h>
00027 #include <stdint.h>
00028 #include <stdio.h>
00029 #include <errno.h>
00030 #include <sys/types.h>
00031 #include <string.h>
00032
00033 #include <yyast/utils.h>
00034 #include <yyast/error.h>
00035
00036
00037 size_t ya_string_escape(uint8_t *string, size_t string_size, int raw)
00038 {
00039 uint8_t c;
00040 unsigned int i, j;
00041 int escape = 0;
00042 int base = 0;
00043 int count = 0;
00044 int32_t code_point = 0;
00045
00046 for (i = 0, j = 0; i < string_size; i++) {
00047 c = string[i];
00048 if (count) {
00049
00050 if (c >= '0' && c <= '9') {
00051 code_point = (code_point << 4) | (c - '0');
00052 } else if (c >= 'a' && c <= 'f') {
00053 code_point = (code_point << 4) | (c - 'a' + 10);
00054 } else if (c >= 'A' && c <= 'F') {
00055 code_point = (code_point << 4) | (c - 'A' + 10);
00056 } else {
00057 ya_error("Could not decode hex escape character.");
00058 }
00059
00060
00061 if (--count == 0) {
00062 if (code_point <= 0x7f) {
00063 string[j++] = code_point;
00064 } else if (code_point <= 0x7ff) {
00065 string[j++] = 0xc0 | ((code_point >> 6) & 0x1f);
00066 string[j++] = 0x80 | ((code_point ) & 0x3f);
00067 } else if (code_point <= 0xffff) {
00068 string[j++] = 0xe0 | ((code_point >> 12) & 0x0f);
00069 string[j++] = 0x80 | ((code_point >> 6) & 0x3f);
00070 string[j++] = 0x80 | ((code_point ) & 0x3f);
00071 } else if (code_point <= 0x1fffff) {
00072 string[j++] = 0xf0 | ((code_point >> 18) & 0x07);
00073 string[j++] = 0x80 | ((code_point >> 12) & 0x3f);
00074 string[j++] = 0x80 | ((code_point >> 6) & 0x3f);
00075 string[j++] = 0x80 | ((code_point ) & 0x3f);
00076 } else if (code_point <= 0x3ffffff) {
00077 string[j++] = 0xf8 | ((code_point >> 24) & 0x03);
00078 string[j++] = 0x80 | ((code_point >> 18) & 0x3f);
00079 string[j++] = 0x80 | ((code_point >> 12) & 0x3f);
00080 string[j++] = 0x80 | ((code_point >> 6) & 0x3f);
00081 string[j++] = 0x80 | ((code_point ) & 0x3f);
00082 } else if (code_point <= 0x7fffffff) {
00083 string[j++] = 0xfc | ((code_point >> 30) & 0x01);
00084 string[j++] = 0x80 | ((code_point >> 24) & 0x3f);
00085 string[j++] = 0x80 | ((code_point >> 18) & 0x3f);
00086 string[j++] = 0x80 | ((code_point >> 12) & 0x3f);
00087 string[j++] = 0x80 | ((code_point >> 6) & 0x3f);
00088 string[j++] = 0x80 | ((code_point ) & 0x3f);
00089 } else {
00090 ya_error("Could not encode code point %lli.", (long long)code_point);
00091 }
00092 string[j++] = code_point;
00093 }
00094
00095 } else if (escape) {
00096 escape = 0;
00097
00098 switch (raw) {
00099 case 2:
00100 switch (c) {
00101 case '/': string[j++] = '/'; break;
00102 default: string[j++] = '\\'; string[j++] = c;
00103 }
00104 break;
00105 case 1:
00106 switch (c) {
00107 case '"': string[j++] = '"'; break;
00108 default: string[j++] = '\\'; string[j++] = c;
00109 }
00110 break;
00111 default:
00112 switch (c) {
00113 case 'n': string[j++] = '\n'; break;
00114 case 'r': string[j++] = '\r'; break;
00115 case 't': string[j++] = '\t'; break;
00116 case '"': string[j++] = '"'; break;
00117 case '/': string[j++] = '/'; break;
00118 case '\\': string[j++] = '\\'; break;
00119 case 'x': base = 16; count = 2; code_point = 0; break;
00120 case 'u': base = 16; count = 4; code_point = 0; break;
00121 case 'U': base = 16; count = 8; code_point = 0; break;
00122 default: string[j++] = '\\'; string[j++] = c;
00123 }
00124 }
00125 } else if (c == '\\') {
00126
00127 escape = 1;
00128
00129 } else {
00130 string[j++] = c;
00131 }
00132 }
00133
00134
00135 if (escape) {
00136 string[j++] = '\\';
00137 }
00138
00139 return j;
00140 }
00141
00142 char *ya_new_extension(char *filename, char *new_extension)
00143 {
00144 char *filename_result;
00145
00146 char *filename_copy = strdup(filename);
00147
00148 char *last_dot = strrchr(filename_copy, '.');
00149
00150 if (last_dot) {
00151
00152 *last_dot = 0;
00153 }
00154
00155
00156 if (asprintf(&filename_result, "%s.%s", filename_copy, new_extension) == -1) {
00157 perror("Could not allocate filename with extension\n");
00158 abort();
00159 }
00160
00161 free(filename_copy);
00162
00163 return filename_result;
00164 }
00165