Prototype game engine for Heroes of Might & Magic, featuring a gameplay plot-twist...
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

837 řádky
24KB

  1. #ifndef null
  2. #define null ((void *) 0)
  3. #endif
  4. enum {
  5. false,
  6. true
  7. };
  8. enum {
  9. file_type_text, file_type_common_assembly, file_type_flat_assembly, file_type_gnu_assembly,
  10. file_type_netwide_assembly, file_type_yet_another_assembly, file_type_c_source, file_type_c_header,
  11. file_type_ada_body, file_type_ada_specification, file_type_cpp_source, file_type_cpp_header,
  12. file_type_count
  13. };
  14. enum {
  15. effect_normal, effect_bold, effect_italic, effect_underline, effect_blink, effect_reverse,
  16. effect_count
  17. };
  18. enum {
  19. colour_grey, colour_red, colour_green, colour_yellow, colour_blue, colour_pink, colour_cyan, colour_white,
  20. colour_count
  21. };
  22. enum {
  23. character_null, character_start_header, character_start_text, character_end_text,
  24. character_end_transmission, character_enquiry, character_acknowledge, character_bell,
  25. character_backspace, character_tab_horizontal, character_line_feed, character_tab_vertical,
  26. character_form_feed, character_carriage_return, character_shift_out, character_shift_in,
  27. character_data_link_escape, character_device_control_1, character_device_control_2, character_device_control_3,
  28. character_device_control_4, character_not_acknowledge, character_synchronous_idle, character_end_transmission_block,
  29. character_cancel, character_end_medium, character_substitute, character_escape,
  30. character_file_separator, character_group_separator, character_record_separator, character_unit_separator
  31. };
  32. enum {
  33. signal_none,
  34. signal_any,
  35. signal_a, signal_b, signal_c, signal_d, signal_e, signal_f, signal_g, signal_h,
  36. signal_i, signal_j, signal_k, signal_l, signal_m, signal_n, signal_o, signal_p,
  37. signal_q, signal_r, signal_s, signal_t, signal_u, signal_v, signal_w, signal_x,
  38. signal_y, signal_z, signal_0, signal_1, signal_2, signal_3, signal_4, signal_5,
  39. signal_6, signal_7, signal_8, signal_9, signal_escape, signal_tabulator, signal_return, signal_new_line,
  40. signal_slash, signal_backslash, signal_quote, signal_backquote, signal_space, signal_backspace, signal_dot, signal_comma,
  41. signal_cite, signal_caps_lock, signal_l_bracket, signal_r_bracket, signal_minus, signal_equal,
  42. signal_count
  43. };
  44. static void out (void * data, int size);
  45. extern void die (void);
  46. extern void echo (char * data);
  47. extern void fatal_failure (int condition, char * message);
  48. extern void limit (int * value, int minimum, int maximum);
  49. extern void * allocate (int size);
  50. extern void * reallocate (void * data, int size);
  51. extern void * deallocate (void * data);
  52. extern int file_open (char * name, int mode);
  53. extern int file_close (int file);
  54. extern void file_read (int file, void * data, int size);
  55. extern void file_write (int file, void * data, int size);
  56. extern int file_seek (int file, int whence);
  57. extern int file_size (char * name);
  58. extern int file_type (char * name);
  59. extern void * file_record (char * name);
  60. extern char * file_import (char * name);
  61. extern void file_export (char * name, void * data);
  62. extern void file_list_import (char * name);
  63. extern void file_list_export (char * name);
  64. extern void file_list_insert_character (char character, int position);
  65. extern void file_list_remove_character (int position);
  66. extern void file_list_delete (void);
  67. extern int character_compare_array (char character, char * character_array);
  68. extern int character_count (char * string, char this, int from, int to, char stop);
  69. extern int string_length (char * string);
  70. extern char * string_reverse_limit (char * string, int limit);
  71. extern char * string_reverse (char * string);
  72. extern char * string_delete (char * string, int length);
  73. extern int string_compare (char * string_0, char * string_1);
  74. extern char * string_copy (char * string_0, char * string_1);
  75. extern char * string_concatenate (char * string_0, char * string_1);
  76. extern int string_compare_limit (char * string_0, char * string_1, int limit);
  77. extern char * string_copy_limit (char * string_0, char * string_1, int limit);
  78. extern char * string_concatenate_limit (char * string_0, char * string_1, int limit);
  79. extern char * string_realign (char * string, int amount, char character);
  80. extern void terminal_clear (void);
  81. extern void terminal_colour (int colour, int effect);
  82. extern void terminal_cancel (void);
  83. extern void terminal_show_cursor (int show);
  84. extern char * number_to_string (int number);
  85. extern char * format_to_string (int number, int sigmoid, int base, int amount, char character);
  86. extern int random_integer (int minimum, int maximum);
  87. extern int syntax_define (int enrange, int derange, char * begin, char * end, char escape, int colour, int effect);
  88. extern int syntax_select (char * string, int * length);
  89. #include <stdlib.h>
  90. #include <unistd.h>
  91. #include <fcntl.h>
  92. #include <time.h>
  93. static int file_list_active = 0;
  94. static int file_list_count = 0;
  95. static int * file_list_mark = null;
  96. static int * file_list_size = null;
  97. static char * * file_list_name = null;
  98. static char * * file_list_data = null;
  99. static int syntax_count = 0;
  100. static int syntax_active = false;
  101. static int * syntax_enrange = null;
  102. static int * syntax_derange = null;
  103. static char * * syntax_begin = null;
  104. static char * * syntax_end = null;
  105. static char * syntax_escape = null;
  106. static int * syntax_colour = null;
  107. static int * syntax_effect = null;
  108. void out (void * data, int size) {
  109. fatal_failure (data == null, "out: Failed to write to standard output, data is null pointer.");
  110. fatal_failure (size == 0, "out: Failed to write to standard output, size is zero.");
  111. (void) write (STDOUT_FILENO, data, (unsigned long int) size);
  112. }
  113. void die (void) {
  114. exit (-1);
  115. }
  116. void echo (char * data) {
  117. if (data == null) {
  118. return;
  119. }
  120. out (data, string_length (data));
  121. }
  122. void fatal_failure (int condition, char * message) {
  123. if (condition != 0) {
  124. echo ("[\033[1;31mExiting\033[0m] ");
  125. echo (message);
  126. echo ("\n");
  127. exit (EXIT_FAILURE);
  128. }
  129. }
  130. void limit (int * value, int minimum, int maximum) {
  131. if ( value == null ) { return; }
  132. if (* value <= minimum) { * value = minimum; }
  133. if (* value >= maximum) { * value = maximum; }
  134. }
  135. void * allocate (int size) {
  136. char * data = null;
  137. if (size <= 0) {
  138. return (null);
  139. }
  140. data = calloc ((unsigned long int) size, sizeof (* data));
  141. fatal_failure (data == null, "standard : allocate : Failed to allocate memory, internal function 'calloc' returned null pointer.");
  142. return ((void *) data);
  143. }
  144. void * reallocate (void * data, int size) {
  145. if (size <= 0) {
  146. return (data);
  147. }
  148. data = realloc (data, (unsigned long int) size);
  149. fatal_failure (data == null, "standard : reallocate: Failed to reallocate memory, internal function 'realloc' returned null pointer.");
  150. /* Set new data to 0. */
  151. return (data);
  152. }
  153. void * deallocate (void * data) {
  154. if (data != null) {
  155. free (data);
  156. }
  157. return (null);
  158. }
  159. int file_open (char * name, int mode) {
  160. int descriptor = -1;
  161. fatal_failure (name == null, "file_open: Failed to open file, name is null pointer.");
  162. descriptor = open (name, mode);
  163. fatal_failure (descriptor == -1, "file_open: Failed to open file, function open returned invalid descriptor.");
  164. return (descriptor);
  165. }
  166. int file_close (int file) {
  167. fatal_failure (file == -1, "file_close: Failed to close file, invalid file descriptor.");
  168. fatal_failure (close (file) == -1, "file_close: Failed to close file, function close returned invalid code.");
  169. return (-1);
  170. }
  171. void file_read (int file, void * data, int size) {
  172. fatal_failure (file == -1, "file_read: Failed to read from file, invalid descriptor.");
  173. fatal_failure (data == null, "file_read: Failed to read from file, data is null pointer.");
  174. fatal_failure (size == 0, "file_read: Failed to read from file, size is zero.");
  175. (void) read (file, data, (unsigned long int) size);
  176. }
  177. void file_write (int file, void * data, int size) {
  178. fatal_failure (file == -1, "file_write: Failed to write to file, invalid descriptor.");
  179. fatal_failure (data == null, "file_write: Failed to write to file, data is null pointer.");
  180. fatal_failure (size == 0, "file_write: Failed to write to file, size is zero.");
  181. (void) write (file, data, (unsigned long int) size);
  182. }
  183. int file_seek (int file, int whence) {
  184. fatal_failure (file == -1, "file_seek: Failed to seek in file, invalid descriptor.");
  185. return ((int) lseek (file, 0, whence));
  186. }
  187. int file_size (char * name) {
  188. int size = -1;
  189. int file = -1;
  190. file = file_open (name, O_RDONLY);
  191. size = lseek (file, 0, SEEK_END);
  192. fatal_failure (size == -1, "file_size: Failed to get size of file, invalid file size.");
  193. file = file_close (file);
  194. return (size);
  195. }
  196. int file_type (char * name) {
  197. char * file_type_data [file_type_count] = {
  198. ".txt", ".s", ".fasm", ".gasm", ".nasm", ".yasm", ".c", ".h",
  199. ".adb", ".ads", ".cpp", ".hpp"
  200. };
  201. int type = 0;
  202. while (* name != '.') {
  203. ++name;
  204. }
  205. for (type = 0; type != file_type_count; ++type) {
  206. if (string_compare (name, file_type_data [type]) != 0) {
  207. return (type);
  208. }
  209. }
  210. return (-1);
  211. }
  212. void * file_record (char * name) {
  213. int file = -1;
  214. int size = -1;
  215. char * data = null;
  216. fatal_failure (name == null, "file_import: Failed to import file, name is null pointer.");
  217. file = file_open (name, O_RDONLY);
  218. size = file_size (name);
  219. data = allocate (size);
  220. file_read (file, data, size);
  221. file = file_close (file);
  222. return (data);
  223. }
  224. char * file_import (char * name) {
  225. int file = -1;
  226. int size = -1;
  227. char * data = null;
  228. fatal_failure (name == null, "file_import: Failed to import file, name is null pointer.");
  229. file = file_open (name, O_RDONLY);
  230. size = file_size (name) + 1;
  231. data = allocate (size);
  232. file_read (file, data, size - 1);
  233. data [size - 1] = '\0';
  234. file = file_close (file);
  235. return (data);
  236. }
  237. void file_export (char * name, void * data) {
  238. (void) name;
  239. (void) data;
  240. }
  241. void file_list_import (char * name) {
  242. fatal_failure (name == null, "file_list_import: Failed to import file, name is null pointer.");
  243. ++file_list_count;
  244. file_list_active = file_list_count - 1;
  245. file_list_mark = reallocate (file_list_mark, (int) sizeof (* file_list_mark) * file_list_count);
  246. file_list_size = reallocate (file_list_size, (int) sizeof (* file_list_size) * file_list_count);
  247. file_list_name = reallocate (file_list_name, (int) sizeof (* file_list_name) * file_list_count);
  248. file_list_data = reallocate (file_list_data, (int) sizeof (* file_list_data) * file_list_count);
  249. file_list_mark [file_list_active] = -1;
  250. file_list_size [file_list_active] = -1;
  251. file_list_name [file_list_active] = null;
  252. file_list_data [file_list_active] = null;
  253. file_list_name [file_list_active] = allocate (string_length (name) + 1);
  254. (void) string_copy_limit (file_list_name [file_list_active], name, string_length (name) + 1);
  255. file_list_mark [file_list_active] = open (name, O_RDWR);
  256. fatal_failure (file_list_mark [file_list_active] == -1, "file_list_import: Failed to open file, function open returned invalid descriptor.");
  257. file_list_size [file_list_active] = (int) lseek (file_list_mark [file_list_active], 0, SEEK_END) + 1;
  258. (void) lseek (file_list_mark [file_list_active], 0, SEEK_SET);
  259. file_list_data [file_list_active] = allocate (file_list_size [file_list_active]);
  260. (void) read (file_list_mark [file_list_active], file_list_data [file_list_active], (unsigned long int) (file_list_size [file_list_active] - 1));
  261. close (file_list_mark [file_list_active]);
  262. file_list_data [file_list_active] [file_list_size [file_list_active] - 1] = '\0';
  263. }
  264. void file_list_export (char * name) {
  265. fatal_failure (name == null, "file_list_export: Failed to export file, name is null pointer.");
  266. file_list_mark [file_list_active] = open (name, O_WRONLY | O_CREAT | O_TRUNC);
  267. (void) write (file_list_mark [file_list_active], file_list_data [file_list_active], (unsigned long int) file_list_size [file_list_active]);
  268. close (file_list_mark [file_list_active]);
  269. }
  270. void file_list_insert_character (char character, int position) {
  271. int offset;
  272. ++file_list_size [file_list_active];
  273. if (file_list_size [file_list_active] < string_length (file_list_data [file_list_active])) {
  274. file_list_data [file_list_active] = reallocate (file_list_data [file_list_active], file_list_size [file_list_active]);
  275. }
  276. file_list_data [file_list_active] = reallocate (file_list_data [file_list_active], file_list_size [file_list_active]);
  277. for (offset = file_list_size [file_list_active] - 1; offset != position; --offset) {
  278. file_list_data [file_list_active] [offset] = file_list_data [file_list_active] [offset - 1];
  279. }
  280. file_list_data [file_list_active] [position] = character;
  281. }
  282. void file_list_remove_character (int position) {
  283. int offset;
  284. if (position == 0) {
  285. return;
  286. }
  287. --file_list_size [file_list_active];
  288. for (offset = position - 1; offset != file_list_size [file_list_active] - 1; ++offset) {
  289. file_list_data [file_list_active] [offset] = file_list_data [file_list_active] [offset + 1];
  290. }
  291. file_list_data [file_list_active] [offset] = '\0';
  292. }
  293. void file_list_delete (void) {
  294. int i;
  295. for (i = 0; i != file_list_count; ++i) {
  296. file_list_name [i] = deallocate (file_list_name [i]);
  297. file_list_data [i] = deallocate (file_list_data [i]);
  298. }
  299. file_list_mark = deallocate (file_list_mark);
  300. file_list_size = deallocate (file_list_size);
  301. file_list_name = deallocate (file_list_name);
  302. file_list_data = deallocate (file_list_data);
  303. }
  304. int character_compare_array (char character, char * character_array) {
  305. int i = 0;
  306. do {
  307. if (character == character_array [i]) {
  308. return (1);
  309. }
  310. } while (++i != string_length (character_array));
  311. return (0);
  312. }
  313. int character_count (char * string, char this, int from, int to, char stop) {
  314. int count;
  315. for (count = 0; (from != to) && (string [from] != stop); from += ((to < from) ? -1 : 1)) {
  316. count += (int) ((string [from] == this) || (this == '\0'));
  317. }
  318. return (count);
  319. }
  320. int string_length (char * string) {
  321. int length;
  322. if (string == null) {
  323. return (0);
  324. }
  325. for (length = 0; string [length] != '\0'; ++length);
  326. return (length);
  327. }
  328. char * string_reverse_limit (char * string, int limit) {
  329. int i;
  330. fatal_failure (string == null, "string_reverse: String is null pointer.");
  331. for (i = 0; i < limit / 2; ++i) {
  332. char temporary = string [i];
  333. string [i] = string [limit - 1 - i];
  334. string [limit - 1 - i] = temporary;
  335. }
  336. return (string);
  337. }
  338. char * string_reverse (char * string) {
  339. return (string_reverse_limit (string, string_length (string)));
  340. }
  341. char * string_delete (char * string, int length) {
  342. int i;
  343. if ((string == null) || (length <= 0)) {
  344. return (string);
  345. }
  346. for (i = 0; i != length; ++i) {
  347. string [i] = '\0';
  348. }
  349. return (string);
  350. }
  351. int string_compare (char * string_0, char * string_1) {
  352. int i = 0;
  353. fatal_failure (string_0 == null, "string_compare: Destination string is null pointer.");
  354. fatal_failure (string_1 == null, "string_compare: Source string is null pointer.");
  355. for (i = 0; (string_0 [i] != '\0') && (string_1 [i] != '\0'); ++i) {
  356. if (string_0 [i] != string_1 [i]) {
  357. return (0);
  358. }
  359. }
  360. return (1);
  361. }
  362. char * string_copy (char * string_0, char * string_1) {
  363. int i = 0;
  364. fatal_failure (string_0 == null, "string_copy: Destination string is null pointer.");
  365. fatal_failure (string_1 == null, "string_copy: Source string is null pointer.");
  366. for (i = 0; i != string_length (string_1) + 1; ++i) {
  367. string_0 [i] = string_1 [i];
  368. }
  369. return (string_0);
  370. }
  371. char * string_concatenate (char * string_0, char * string_1) {
  372. fatal_failure (string_0 == null, "string_concatenate: Destination string is null pointer.");
  373. fatal_failure (string_1 == null, "string_concatenate: Source string is null pointer.");
  374. string_0 += string_length (string_0);
  375. while (* string_1 != '\0') {
  376. * string_0++ = * string_1++;
  377. /*++string_0;
  378. ++string_1;*/
  379. }
  380. * string_0 = '\0';
  381. return (string_0);
  382. }
  383. int string_compare_limit (char * string_0, char * string_1, int limit) {
  384. int i = 0;
  385. fatal_failure (string_0 == null, "string_compare_limit: Destination string is null pointer.");
  386. fatal_failure (string_1 == null, "string_compare_limit: Source string is null pointer.");
  387. for (i = 0; i != limit; ++i) {
  388. if (string_0 [i] != string_1 [i]) {
  389. return (0);
  390. }
  391. }
  392. return (1);
  393. }
  394. char * string_copy_limit (char * string_0, char * string_1, int limit) {
  395. int i = 0;
  396. fatal_failure (string_0 == null, "string_copy_limit: Destination string is null pointer.");
  397. fatal_failure (string_1 == null, "string_copy_limit: Source string is null pointer.");
  398. if (limit <= 0) {
  399. return (string_0);
  400. }
  401. for (i = 0; i != limit; ++i) {
  402. string_0 [i] = string_1 [i];
  403. }
  404. return (string_0);
  405. }
  406. char * string_concatenate_limit (char * string_0, char * string_1, int limit) {
  407. int i = 0;
  408. int length_0 = 0;
  409. int length_1 = 0;
  410. fatal_failure (string_0 == null, "string_concatenate_limit: Destination string is null pointer.");
  411. fatal_failure (string_1 == null, "string_concatenate_limit: Source string is null pointer.");
  412. if (limit <= 0) {
  413. return (string_0);
  414. }
  415. length_0 = string_length (string_0);
  416. length_1 = string_length (string_1);
  417. for (i = 0; (i != length_1) && (i != limit); ++i) {
  418. string_0 [length_0 + i] = string_1 [i];
  419. }
  420. return (string_0);
  421. }
  422. char * string_realign (char * string, int amount, char character) {
  423. int offset, length;
  424. length = string_length (string);
  425. for (offset = 0; offset != length; ++offset) {
  426. string [amount - offset - 1] = string [length - offset - 1];
  427. }
  428. for (offset = 0; offset != amount - length; ++offset) {
  429. string [offset] = character;
  430. }
  431. string [amount] = '\0';
  432. return (string);
  433. }
  434. void terminal_clear (void) {
  435. echo ("\033[2J\033[H");
  436. }
  437. void terminal_colour (int colour, int effect) {
  438. char format [8] = "\033[ ;3 m";
  439. format [2] = (char) (effect % effect_count) + '0';
  440. format [5] = (char) (colour % colour_count) + '0';
  441. echo (format);
  442. }
  443. void terminal_cancel (void) {
  444. echo ("\033[0m");
  445. }
  446. void terminal_show_cursor (int show) {
  447. if (show != 0) {
  448. echo ("\033[?25h");
  449. } else {
  450. echo ("\033[?25l");
  451. }
  452. }
  453. char * number_to_string (int number) {
  454. int i, sigmoid;
  455. static char string [32];
  456. string_delete (string, 32);
  457. if (number == 0) {
  458. string [0] = '0';
  459. string [1] = '\0';
  460. return (string);
  461. }
  462. if (number < 0) {
  463. number *= -1;
  464. sigmoid = 1;
  465. } else {
  466. sigmoid = 0;
  467. }
  468. for (i = (string [0] == '-'); number != 0; ++i) {
  469. string [i] = (char) (number % 10) + '0';
  470. number /= 10;
  471. }
  472. if (sigmoid != 0) {
  473. string [i] = '-';
  474. ++i;
  475. }
  476. string [i] = '\0';
  477. string_reverse (string);
  478. return (string);
  479. }
  480. char * format_to_string (int number, int sigmoid, int base, int amount, char character) {
  481. int i;
  482. static char string [32];
  483. string_delete (string, 32);
  484. if (number == 0) {
  485. string [0] = '0';
  486. string [1] = '\0';
  487. string_realign (string, amount, character);
  488. return (string);
  489. }
  490. if (number < 0) {
  491. number *= -1;
  492. }
  493. for (i = (string [0] == '-'); number != 0; ++i) {
  494. string [i] = "0123456789ABCDEF" [number % base];
  495. number /= base;
  496. }
  497. if (sigmoid != 0) {
  498. string [i] = '-';
  499. ++i;
  500. }
  501. string [i] = '\0';
  502. string_reverse (string);
  503. string_realign (string, amount, character);
  504. return (string);
  505. }
  506. static void syntax_delete (void) {
  507. int offset;
  508. if (syntax_active == false) {
  509. return;
  510. }
  511. for (offset = 0; offset < syntax_count; ++offset) {
  512. syntax_begin [offset] = deallocate (syntax_begin [offset]);
  513. syntax_end [offset] = deallocate (syntax_end [offset]);
  514. }
  515. syntax_enrange = deallocate (syntax_enrange);
  516. syntax_derange = deallocate (syntax_derange);
  517. syntax_begin = deallocate (syntax_begin);
  518. syntax_end = deallocate (syntax_end);
  519. syntax_escape = deallocate (syntax_escape);
  520. syntax_colour = deallocate (syntax_colour);
  521. syntax_effect = deallocate (syntax_effect);
  522. syntax_active = false;
  523. syntax_count = 0;
  524. }
  525. int random_integer (int minimum, int maximum) {
  526. return (((int) rand () % (maximum - minimum + 1)) + minimum);
  527. }
  528. int syntax_define (int enrange, int derange, char * begin, char * end, char escape, int colour, int effect) {
  529. if (syntax_active == false) {
  530. syntax_active = true;
  531. atexit (syntax_delete);
  532. }
  533. fatal_failure (begin == null, "syntax_define: Begin string is null pointer.");
  534. fatal_failure (end == null, "syntax_define: End string is null pointer.");
  535. ++syntax_count;
  536. syntax_enrange = reallocate (syntax_enrange, syntax_count * (int) sizeof (* syntax_enrange));
  537. syntax_derange = reallocate (syntax_derange, syntax_count * (int) sizeof (* syntax_derange));
  538. syntax_begin = reallocate (syntax_begin, syntax_count * (int) sizeof (* syntax_begin));
  539. syntax_end = reallocate (syntax_end, syntax_count * (int) sizeof (* syntax_end));
  540. syntax_escape = reallocate (syntax_escape, syntax_count * (int) sizeof (* syntax_escape));
  541. syntax_colour = reallocate (syntax_colour, syntax_count * (int) sizeof (* syntax_colour));
  542. syntax_effect = reallocate (syntax_effect, syntax_count * (int) sizeof (* syntax_effect));
  543. syntax_begin [syntax_count - 1] = allocate ((string_length (begin) + 1) * (int) sizeof (* * syntax_begin));
  544. syntax_end [syntax_count - 1] = allocate ((string_length (end) + 1) * (int) sizeof (* * syntax_end));
  545. syntax_enrange [syntax_count - 1] = enrange;
  546. syntax_derange [syntax_count - 1] = derange;
  547. syntax_escape [syntax_count - 1] = escape;
  548. syntax_colour [syntax_count - 1] = colour;
  549. syntax_effect [syntax_count - 1] = effect;
  550. string_copy (syntax_begin [syntax_count - 1], begin);
  551. string_copy (syntax_end [syntax_count - 1], end);
  552. return (syntax_count - 1);
  553. }
  554. int syntax_select (char * string, int * length) {
  555. int offset, subset, select;
  556. fatal_failure (syntax_active == false, "syntax_select: Syntax is not active.");
  557. fatal_failure (string == null, "syntax_select: String is null.");
  558. fatal_failure (length == null, "syntax_select: Length is null.");
  559. for (select = offset = 0; select != syntax_count; ++select) {
  560. if (syntax_enrange [select] == false) {
  561. if (syntax_derange [select] == false) {
  562. if (string_compare_limit (string, syntax_begin [select], string_length (syntax_begin [select])) == true) {
  563. break;
  564. }
  565. } else {
  566. if ((string_compare_limit (string, syntax_begin [select], string_length (syntax_begin [select])) == true)
  567. && (character_compare_array (string [offset + string_length (syntax_begin [select])], syntax_end [select]) == true)) {
  568. break;
  569. }
  570. }
  571. } else {
  572. for (subset = 0; subset != string_length (syntax_begin [select]); ++subset) {
  573. if (string [offset] == syntax_begin [select] [subset]) {
  574. goto selected;
  575. }
  576. }
  577. }
  578. }
  579. selected:
  580. if (select >= syntax_count) {
  581. * length = 1;
  582. return (syntax_count);
  583. }
  584. for (offset = 1; string [offset - 1] != '\0'; ++offset) {
  585. if (string [offset] == syntax_escape [select]) {
  586. ++offset;
  587. continue;
  588. }
  589. if (syntax_derange [select] == false) {
  590. if (string_compare_limit (& string [offset], syntax_end [select], string_length (syntax_end [select])) == true) {
  591. * length = offset + string_length (syntax_end [select]);
  592. return (select);
  593. }
  594. } else {
  595. subset = 0;
  596. if (string_compare (syntax_end [select], "") == false) {
  597. break;
  598. } do {
  599. if (string [offset] == syntax_end [select] [subset]) {
  600. * length = offset;
  601. goto finished;
  602. }
  603. } while (++subset != string_length (syntax_end [select]));
  604. }
  605. }
  606. finished:
  607. return (select);
  608. }