cc_strings.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /* Copyright (C) 2016 Jeremiah Orians
  2. * Copyright (C) 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  3. * This file is part of M2-Planet.
  4. *
  5. * M2-Planet is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * M2-Planet is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "cc.h"
  19. #include <stdint.h>
  20. int char2hex(int c);
  21. struct token_list* emit(char *s, struct token_list* head);
  22. void require(int bool, char* error);
  23. char upcase(char a)
  24. {
  25. if(in_set(a, "abcdefghijklmnopqrstuvwxyz"))
  26. {
  27. a = a - 32;
  28. }
  29. return a;
  30. }
  31. int hexify(int c, int high)
  32. {
  33. int i = char2hex(c);
  34. if(0 > i)
  35. {
  36. file_print("Tried to print non-hex number\n", stderr);
  37. exit(EXIT_FAILURE);
  38. }
  39. if(high)
  40. {
  41. i = i << 4;
  42. }
  43. return i;
  44. }
  45. int escape_lookup(char* c);
  46. int weird(char* string)
  47. {
  48. int c;
  49. string = string + 1;
  50. weird_reset:
  51. c = string[0];
  52. if(0 == c) return FALSE;
  53. if('\\' == c)
  54. {
  55. c = escape_lookup(string);
  56. if('x' == string[1]) string = string + 2;
  57. string = string + 1;
  58. }
  59. if(!in_set(c, "\t\n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")) return TRUE;
  60. if(in_set(c, " \t\n\r") && (':' == string[1])) return TRUE;
  61. string = string + 1;
  62. goto weird_reset;
  63. }
  64. /* Lookup escape values */
  65. int escape_lookup(char* c)
  66. {
  67. if('\\' != c[0]) return c[0];
  68. if(c[1] == 'x')
  69. {
  70. int t1 = hexify(c[2], TRUE);
  71. int t2 = hexify(c[3], FALSE);
  72. return t1 + t2;
  73. }
  74. else if(c[1] == '0') return 0;
  75. else if(c[1] == 'a') return 7;
  76. else if(c[1] == 'b') return 8;
  77. else if(c[1] == 't') return 9;
  78. else if(c[1] == 'n') return 10;
  79. else if(c[1] == 'v') return 11;
  80. else if(c[1] == 'f') return 12;
  81. else if(c[1] == 'r') return 13;
  82. else if(c[1] == 'e') return 27;
  83. else if(c[1] == '"') return 34;
  84. else if(c[1] == '\'') return 39;
  85. else if(c[1] == '\\') return 92;
  86. file_print("Unknown escape received: ", stderr);
  87. file_print(c, stderr);
  88. file_print(" Unable to process\n", stderr);
  89. exit(EXIT_FAILURE);
  90. }
  91. /* Deal with human strings */
  92. char* collect_regular_string(char* string)
  93. {
  94. string_index = 0;
  95. collect_regular_string_reset:
  96. require((MAX_STRING - 3) > string_index, "Attempt at parsing regular string exceeds max length\n");
  97. if(string[0] == '\\')
  98. {
  99. hold_string[string_index] = escape_lookup(string);
  100. if (string[1] == 'x') string = string + 2;
  101. string = string + 2;
  102. }
  103. else
  104. {
  105. hold_string[string_index] = string[0];
  106. string = string + 1;
  107. }
  108. string_index = string_index + 1;
  109. if(string[0] != 0) goto collect_regular_string_reset;
  110. hold_string[string_index] = '"';
  111. hold_string[string_index + 1] = '\n';
  112. char* message = calloc(string_index + 3, sizeof(char));
  113. require(NULL != message, "Exhusted memory while storing regular string\n");
  114. copy_string(message, hold_string, string_index + 2);
  115. reset_hold_string();
  116. return message;
  117. }
  118. /* Deal with non-human strings */
  119. char* collect_weird_string(char* string)
  120. {
  121. string_index = 1;
  122. int temp;
  123. char* table = "0123456789ABCDEF";
  124. hold_string[0] = '\'';
  125. collect_weird_string_reset:
  126. require((MAX_STRING - 6) > string_index, "Attempt at parsing weird string exceeds max length\n");
  127. string = string + 1;
  128. hold_string[string_index] = ' ';
  129. temp = escape_lookup(string);
  130. hold_string[string_index + 1] = table[(temp >> 4)];
  131. hold_string[string_index + 2] = table[(temp & 15)];
  132. if(string[0] == '\\')
  133. {
  134. if(string[1] == 'x') string = string + 2;
  135. string = string + 1;
  136. }
  137. string_index = string_index + 3;
  138. if(string[1] != 0) goto collect_weird_string_reset;
  139. hold_string[string_index] = ' ';
  140. hold_string[string_index + 1] = '0';
  141. hold_string[string_index + 2] = '0';
  142. hold_string[string_index + 3] = '\'';
  143. hold_string[string_index + 4] = '\n';
  144. char* hold = calloc(string_index + 6, sizeof(char));
  145. require(NULL != hold, "Exhusted available memory while attempting to collect a weird string\n");
  146. copy_string(hold, hold_string, string_index + 5);
  147. reset_hold_string();
  148. return hold;
  149. }
  150. /* Parse string to deal with hex characters*/
  151. char* parse_string(char* string)
  152. {
  153. /* the string */
  154. if(weird(string)) return collect_weird_string(string);
  155. else return collect_regular_string(string);
  156. }