Xtandard stuff...
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

757 line
20KB

  1. /*
  2. * Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic
  3. *
  4. * Xtandard is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
  5. * And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
  6. * It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
  7. */
  8. #ifndef XTANDARD_SOURCE
  9. #define XTANDARD_SOURCE
  10. #include <xolatile/xtandard.h>
  11. char * program_name = NULL;
  12. char * program_mode = NULL;
  13. char * program_license = NULL;
  14. char * log_notify = NULL;
  15. int argument_count = 0;
  16. char * * argument_nick = NULL;
  17. char * * argument_name = NULL;
  18. char * argument_input = NULL;
  19. char * argument_output = NULL;
  20. void (* * argument_function) (void) = NULL;
  21. int file_list_active = 0;
  22. int file_list_count = 0;
  23. int * file_list_mark = NULL;
  24. int * file_list_size = NULL;
  25. char * * file_list_name = NULL;
  26. char * * file_list_data = NULL;
  27. void in (void * data, int size) {
  28. fatal_failure (data == NULL, "in: Failed to read from standard input, data is null pointer.");
  29. fatal_failure (size == 0, "in: Failed to read from standard input, size is zero.");
  30. (void) read (STDIN_FILENO, data, (unsigned long int) size);
  31. }
  32. void out (void * data, int size) {
  33. fatal_failure (data == NULL, "out: Failed to write to standard output, data is null pointer.");
  34. fatal_failure (size == 0, "out: Failed to write to standard output, size is zero.");
  35. (void) write (STDOUT_FILENO, data, (unsigned long int) size);
  36. }
  37. void log_in (int type, int flag, char * data) {
  38. char * type_mark [LOG_COUNT] = {
  39. "[\033[0;32mSuccess\033[0m] ",
  40. "[\033[0;33mWarning\033[0m] ",
  41. "[\033[0;31mFailure\033[0m] ",
  42. "[\033[0;34mComment\033[0m] "
  43. };
  44. if ((flag == 0) || (type <= -1) || (type >= LOG_COUNT)) {
  45. return;
  46. }
  47. if (log_notify == NULL) {
  48. log_notify = allocate (string_length (type_mark [type]) + string_length (data) + 2);
  49. } else {
  50. log_notify = reallocate (log_notify, string_length (log_notify) + string_length (type_mark [type]) + string_length (data) + 2);
  51. log_notify [string_length (log_notify)] = '\0';
  52. }
  53. string_concatenate (log_notify, type_mark [type]);
  54. string_concatenate (log_notify, data);
  55. string_concatenate (log_notify, "\n");
  56. }
  57. void log_out (void) {
  58. echo (log_notify);
  59. log_notify = deallocate (log_notify);
  60. }
  61. void echo (char * data) {
  62. if (data == NULL) {
  63. return;
  64. }
  65. out (data, string_length (data));
  66. }
  67. void echo_new_line (void) {
  68. out ("\n", 1);
  69. }
  70. void echo_byte (int byte) {
  71. out ("0123456789ABCDEF" + (byte % 256) / 16, 1);
  72. out ("0123456789ABCDEF" + (byte % 256) % 16, 1);
  73. out (" ", 1);
  74. }
  75. void fatal_failure (int condition, char * message) {
  76. if (condition != 0) {
  77. echo ("\033[1;31m[FATAL_FAILURE]\033[0m ");
  78. echo (message);
  79. echo ("\n");
  80. exit (EXIT_FAILURE);
  81. }
  82. }
  83. void limit (int * value, int minimum, int maximum) {
  84. if (* value <= minimum) {
  85. * value = minimum;
  86. }
  87. if (* value >= maximum) {
  88. * value = maximum;
  89. }
  90. }
  91. void * allocate (int size) {
  92. char * data = NULL;
  93. if (size <= 0) {
  94. return (NULL);
  95. }
  96. data = calloc ((unsigned long int) size, sizeof (* data));
  97. fatal_failure (data == NULL, "allocate: Failed to allocate memory, function calloc returned null pointer.");
  98. return ((void *) data);
  99. }
  100. void * reallocate (void * data, int size) {
  101. if (size <= 0) {
  102. return (data);
  103. }
  104. data = realloc (data, (unsigned long int) size);
  105. fatal_failure (data == NULL, "reallocate: Failed to reallocate memory, function recalloc returned null pointer.");
  106. /* Set new data to 0. */
  107. return (data);
  108. }
  109. void * deallocate (void * data) {
  110. if (data != NULL) {
  111. free (data);
  112. }
  113. return (NULL);
  114. }
  115. void * memorize (int size) { /* I broke this for testing something out... */
  116. static char * buffer = NULL;
  117. char * points = NULL;
  118. static int length = 0;
  119. static int chunks = 0;
  120. static int loling = 1024;
  121. if (size == 0) {
  122. free (buffer);
  123. buffer = NULL;
  124. length = 0;
  125. chunks = 0;
  126. return (NULL);
  127. }
  128. for (; length + size > chunks * loling; ) {
  129. int i;
  130. ++chunks;
  131. buffer = realloc (buffer, (unsigned long int) (chunks * loling));
  132. fatal_failure (buffer == NULL, "memorize: Oh no...");
  133. for (i = (chunks - 1) * loling; i != chunks * loling; ++i) {
  134. buffer [i] = '\0';
  135. }
  136. }
  137. points = & buffer [length];
  138. length += size;
  139. return ((void *) points);
  140. }
  141. void * record (void) {
  142. char * buffer = NULL;
  143. int offset = 0;
  144. int loling = 1024;
  145. buffer = reallocate (buffer, loling);
  146. do {
  147. if ((offset + 1) % loling == 0) {
  148. buffer = reallocate (buffer, ((offset + 1) / loling + 1) * loling);
  149. }
  150. buffer [offset] = '\0';
  151. in (& buffer [offset], sizeof (* buffer));
  152. ++offset;
  153. } while (buffer [offset - 1] != '\0');
  154. buffer [offset - 1] = '\0';
  155. return (buffer);
  156. }
  157. void argument_define (char * nick, char * name, void (* function) (void)) {
  158. fatal_failure (nick == NULL, "argument_define: Failed to define an argument, nick is null pointer.");
  159. fatal_failure (name == NULL, "argument_define: Failed to define an argument, name is null pointer.");
  160. fatal_failure (function == NULL, "argument_define: Failed to define an argument, function is null pointer.");
  161. ++argument_count;
  162. argument_nick = reallocate (argument_nick, argument_count * (int) sizeof (* argument_nick));
  163. argument_name = reallocate (argument_name, argument_count * (int) sizeof (* argument_name));
  164. argument_function = reallocate (argument_function, argument_count * (int) sizeof (* argument_function));
  165. argument_nick [argument_count - 1] = allocate (string_length (nick) + 1);
  166. argument_name [argument_count - 1] = allocate (string_length (name) + 1);
  167. string_copy (argument_nick [argument_count - 1], nick);
  168. string_copy (argument_name [argument_count - 1], name);
  169. argument_function [argument_count - 1] = function;
  170. }
  171. void argument_select (int count, char * * array) {
  172. int index_a = 0;
  173. int index_b = 0;
  174. if ((count == 1) || (array == NULL)) {
  175. return;
  176. }
  177. for (index_a = 1; index_a != count; ++index_a) {
  178. for (index_b = 0; index_b != argument_count; ++index_b) {
  179. if ((string_compare (array [index_a], "-h") != 0) || (string_compare (array [index_a], "--help") != 0)) {
  180. echo ("Printing help...\n");
  181. for (index_b = 0; index_b != argument_count; ++index_b) {
  182. echo ("\t"); echo (argument_nick [index_b]);
  183. echo (" "); echo (argument_name [index_b]);
  184. echo ("\n");
  185. }
  186. fatal_failure (1, "Help printed, terminating...");
  187. } else if ((string_compare (array [index_a], "-i") != 0) || (string_compare (array [index_a], "--input") != 0)) {
  188. ++index_a;
  189. argument_input = array [index_a];
  190. echo ("Selecting input: "); echo (argument_input); echo ("\n");
  191. break;
  192. } else if ((string_compare (array [index_a], "-o") != 0) || (string_compare (array [index_a], "--output") != 0)) {
  193. ++index_a;
  194. argument_output = array [index_a];
  195. echo ("Selecting output: "); echo (argument_output); echo ("\n");
  196. break;
  197. } else if ((string_compare (array [index_a], argument_nick [index_b]) != 0) || (string_compare (array [index_a], argument_name [index_b]) != 0)) {
  198. argument_function [index_b] ();
  199. echo ("Executing: "); echo (argument_name [index_b]); echo ("\n");
  200. break;
  201. }
  202. }
  203. }
  204. }
  205. void argument_delete (void) {
  206. int index;
  207. for (index = 0; index != argument_count; ++index) {
  208. argument_nick [index] = deallocate (argument_nick [index]);
  209. argument_name [index] = deallocate (argument_name [index]);
  210. }
  211. argument_nick = deallocate (argument_nick);
  212. argument_name = deallocate (argument_name);
  213. argument_function = deallocate (argument_function);
  214. }
  215. int file_open (char * name, int mode) {
  216. int descriptor = -1;
  217. fatal_failure (name == NULL, "file_open: Failed to open file, name is null pointer.");
  218. descriptor = open (name, mode);
  219. fatal_failure (descriptor == -1, "file_open: Failed to open file, function open returned invalid descriptor.");
  220. return (descriptor);
  221. }
  222. int file_close (int file) {
  223. fatal_failure (file == -1, "file_close: Failed to close file, invalid file descriptor.");
  224. fatal_failure (close (file) == -1, "file_close: Failed to close file, function close returned invalid code.");
  225. return (-1);
  226. }
  227. void file_read (int file, void * data, int size) {
  228. fatal_failure (file == -1, "file_read: Failed to read from file, invalid descriptor.");
  229. fatal_failure (data == NULL, "file_read: Failed to read from file, data is null pointer.");
  230. fatal_failure (size == 0, "file_read: Failed to read from file, size is zero.");
  231. (void) read (file, data, (unsigned long int) size);
  232. }
  233. void file_write (int file, void * data, int size) {
  234. fatal_failure (file == -1, "file_write: Failed to write to file, invalid descriptor.");
  235. fatal_failure (data == NULL, "file_write: Failed to write to file, data is null pointer.");
  236. fatal_failure (size == 0, "file_write: Failed to write to file, size is zero.");
  237. (void) write (file, data, (unsigned long int) size);
  238. }
  239. int file_seek (int file, int whence) {
  240. fatal_failure (file == -1, "file_seek: Failed to seek in file, invalid descriptor.");
  241. return ((int) lseek (file, 0, whence));
  242. }
  243. int file_size (int file) {
  244. int size = 0;
  245. fatal_failure (file == -1, "file_size: Failed to get size of file, invalid descriptor.");
  246. size = lseek (file, 0, SEEK_END);
  247. (void) lseek (file, 0, SEEK_SET);
  248. fatal_failure (size == -1, "file_size: Failed to get size of file, invalid file size.");
  249. return (size);
  250. }
  251. int file_type (char * name) {
  252. char * file_type_data [FILE_TYPE_COUNT] = {
  253. ".txt", ".s", ".fasm", ".gasm", ".nasm", ".yasm", ".c", ".h",
  254. ".adb", ".ads", ".cpp", ".hpp"
  255. };
  256. int type = 0;
  257. while (* name != '.') {
  258. ++name;
  259. }
  260. for (type = 0; type != FILE_TYPE_COUNT; ++type) {
  261. if (string_compare (name, file_type_data [type]) != 0) {
  262. return (type);
  263. }
  264. }
  265. return (-1);
  266. }
  267. char * file_import (char * name) {
  268. int file = -1;
  269. int size = -1;
  270. char * data = NULL;
  271. fatal_failure (name == NULL, "file_import: Failed to import file, name is null pointer.");
  272. fatal_failure (data != NULL, "file_import: Failed to import file, data is not null pointer.");
  273. file = file_open (name, O_RDONLY);
  274. size = file_size (file) + 1;
  275. data = allocate (size);
  276. file_read (file, data, size - 1);
  277. data [size - 1] = '\0';
  278. file = file_close (file);
  279. return (data);
  280. }
  281. void file_export (char * name, void * data) {
  282. (void) name;
  283. (void) data;
  284. }
  285. void file_list_import (char * name) {
  286. fatal_failure (name == NULL, "file_list_import: Failed to import file, name is null pointer.");
  287. ++file_list_count;
  288. file_list_active = file_list_count - 1;
  289. file_list_mark = reallocate (file_list_mark, (int) sizeof (* file_list_mark) * file_list_count);
  290. file_list_size = reallocate (file_list_size, (int) sizeof (* file_list_size) * file_list_count);
  291. file_list_name = reallocate (file_list_name, (int) sizeof (* file_list_name) * file_list_count);
  292. file_list_data = reallocate (file_list_data, (int) sizeof (* file_list_data) * file_list_count);
  293. file_list_mark [file_list_count - 1] = -1;
  294. file_list_size [file_list_count - 1] = -1;
  295. file_list_name [file_list_count - 1] = NULL;
  296. file_list_data [file_list_count - 1] = NULL;
  297. file_list_name [file_list_count - 1] = allocate (string_length (name) + 1);
  298. (void) string_copy_limit (file_list_name [file_list_count - 1], name, string_length (name) + 1);
  299. file_list_mark [file_list_count - 1] = open (name, O_RDONLY);
  300. fatal_failure (file_list_mark [file_list_count - 1] == -1, "file_list_import: Failed to open file, function open returned invalid descriptor.");
  301. file_list_size [file_list_count - 1] = (int) lseek (file_list_mark [file_list_count - 1], 0, SEEK_END) + 1;
  302. (void) lseek (file_list_mark [file_list_count - 1], 0, SEEK_SET);
  303. file_list_data [file_list_count - 1] = allocate (file_list_size [file_list_count - 1]);
  304. (void) read (file_list_mark [file_list_count - 1], file_list_data [file_list_count - 1], (unsigned long int) (file_list_size [file_list_count - 1] - 1));
  305. close (file_list_mark [file_list_count - 1]);
  306. file_list_data [file_list_count - 1] [file_list_size [file_list_count - 1] - 1] = '\0';
  307. }
  308. void file_list_export (char * name) {
  309. fatal_failure (name == NULL, "file_list_export: Failed to export file, name is null pointer.");
  310. file_list_mark [file_list_active] = open (name, O_WRONLY | O_CREAT | O_TRUNC);
  311. (void) write (file_list_mark [file_list_active], file_list_data [file_list_active], (unsigned long int) file_list_size [file_list_active]);
  312. close (file_list_mark [file_list_active]);
  313. }
  314. void file_list_delete (void) {
  315. int i;
  316. for (i = 0; i != file_list_count; ++i) {
  317. file_list_name [i] = deallocate (file_list_name [i]);
  318. file_list_data [i] = deallocate (file_list_data [i]);
  319. }
  320. file_list_mark = deallocate (file_list_mark);
  321. file_list_size = deallocate (file_list_size);
  322. file_list_name = deallocate (file_list_name);
  323. file_list_data = deallocate (file_list_data);
  324. }
  325. int character_is_uppercase (char character) {
  326. return ((int) ((character >= 'A') && (character <= 'Z')));
  327. }
  328. int character_is_lowercase (char character) {
  329. return ((int) ((character >= 'a') && (character <= 'z')));
  330. }
  331. int character_is_digit (char character) {
  332. return ((int) ((character >= '0') && (character <= '9')));
  333. }
  334. int character_is_blank (char character) {
  335. return ((int) ((character == ' ') || (character == '\t') || (character == '\r') || (character == '\n')));
  336. }
  337. int character_is_alpha (char character) {
  338. return ((character_is_uppercase (character) != 0) || (character_is_lowercase (character) != 0));
  339. }
  340. int character_is_symbol (char character) {
  341. char * symbols = "~!@#$%^&*()+{}|:\"<>?`-=[]\\;',./";
  342. return (character_compare_array (character, symbols, string_length (symbols)));
  343. }
  344. int character_is_visible (char character) {
  345. return ((int) ((character >= ' ') && (character <= '~')));
  346. }
  347. int character_is_invisible (char character) {
  348. return (character_is_visible (character) == 0);
  349. }
  350. int character_is_escape (char character) {
  351. return ((int) (character == '\033'));
  352. }
  353. int character_is_underscore (char character) {
  354. return ((int) (character == '_'));
  355. }
  356. int character_is_hexadecimal (char character) {
  357. char * hexadecimals = "0123456789ABCDEF";
  358. return (character_compare_array (character, hexadecimals, string_length (hexadecimals)));
  359. }
  360. int character_compare_array (char character, char * character_array, int count) {
  361. int i = 0;
  362. do {
  363. if (character == character_array [i]) {
  364. return (1);
  365. }
  366. } while (++i != count);
  367. return (0);
  368. }
  369. int string_length (char * string) {
  370. int length = 0;
  371. if (string == NULL) {
  372. return (0);
  373. }
  374. for (length = 0; string [length] != '\0'; ++length);
  375. return (length);
  376. }
  377. void string_reverse (char * string) {
  378. int i = 0;
  379. int length = 0;
  380. fatal_failure (string == NULL, "string_reverse: String is null pointer.");
  381. length = string_length (string);
  382. for (i = 0; string [i] != '\0'; ++i) {
  383. string [i] = string [length - i];
  384. }
  385. }
  386. void string_delete (char * string, int length) {
  387. int i;
  388. if ((string == NULL) || (length <= 0)) {
  389. return;
  390. }
  391. for (i = 0; i != length; ++i) {
  392. string [i] = '\0';
  393. }
  394. }
  395. int string_compare (char * string_0, char * string_1) {
  396. int i = 0;
  397. fatal_failure (string_0 == NULL, "string_compare: Destination string is null pointer.");
  398. fatal_failure (string_1 == NULL, "string_compare: Source string is null pointer.");
  399. for (i = 0; (string_0 [i] != '\0') && (string_1 [i] != '\0'); ++i) {
  400. if (string_0 [i] != string_1 [i]) {
  401. return (0);
  402. }
  403. }
  404. return (1);
  405. }
  406. void string_copy (char * string_0, char * string_1) {
  407. int i = 0;
  408. fatal_failure (string_0 == NULL, "string_copy: Destination string is null pointer.");
  409. fatal_failure (string_1 == NULL, "string_copy: Source string is null pointer.");
  410. for (i = 0; i != string_length (string_1) + 1; ++i) {
  411. string_0 [i] = string_1 [i];
  412. }
  413. }
  414. void string_concatenate (char * string_0, char * string_1) {
  415. fatal_failure (string_0 == NULL, "string_concatenate: Destination string is null pointer.");
  416. fatal_failure (string_1 == NULL, "string_concatenate: Source string is null pointer.");
  417. string_0 += string_length (string_0);
  418. while (* string_1 != '\0') {
  419. * string_0++ = * string_1++;
  420. /*++string_0;
  421. ++string_1;*/
  422. }
  423. * string_0 = '\0';
  424. }
  425. int string_compare_limit (char * string_0, char * string_1, int limit) {
  426. int i = 0;
  427. fatal_failure (string_0 == NULL, "string_compare_limit: Destination string is null pointer.");
  428. fatal_failure (string_1 == NULL, "string_compare_limit: Source string is null pointer.");
  429. for (i = 0; i != limit; ++i) {
  430. if (string_0 [i] != string_1 [i]) {
  431. return (0);
  432. }
  433. }
  434. return (1);
  435. }
  436. void string_copy_limit (char * string_0, char * string_1, int limit) {
  437. int i = 0;
  438. fatal_failure (string_0 == NULL, "string_copy_limit: Destination string is null pointer.");
  439. fatal_failure (string_1 == NULL, "string_copy_limit: Source string is null pointer.");
  440. if (limit <= 0) {
  441. return;
  442. }
  443. for (i = 0; i != limit; ++i) {
  444. string_0 [i] = string_1 [i];
  445. }
  446. }
  447. void string_concatenate_limit (char * string_0, char * string_1, int limit) {
  448. int i = 0;
  449. int length_0 = 0;
  450. int length_1 = 0;
  451. fatal_failure (string_0 == NULL, "string_concatenate_limit: Destination string is null pointer.");
  452. fatal_failure (string_1 == NULL, "string_concatenate_limit: Source string is null pointer.");
  453. if (limit <= 0) {
  454. return;
  455. }
  456. length_0 = string_length (string_0);
  457. length_1 = string_length (string_1);
  458. for (i = 0; (i != length_1) && (i != limit); ++i) {
  459. string_0 [length_0 + i] = string_1 [i];
  460. }
  461. }
  462. int string_split_space (char * string) {
  463. int i = 0;
  464. int count = 0;
  465. fatal_failure (string == NULL, "string_split_space: Source string is null pointer.");
  466. for (i = 0; string [i] != '\0'; ++i) {
  467. if ((string [i] == ' ') || (string [i] == '\t') || (string [i] == '\n')) {
  468. string [i] = '\0';
  469. ++count;
  470. }
  471. }
  472. return (++count);
  473. }
  474. void memory_delete (void * memory, int length) {
  475. int i = 0;
  476. char * cast = (char *) memory;
  477. fatal_failure (memory == NULL, "memory_delete: Memory is null pointer.");
  478. if (length <= 0) {
  479. return;
  480. }
  481. for (i = 0; i != length; ++i) {
  482. cast [i] = '\0';
  483. }
  484. }
  485. int memory_compare (void * memory, void * source, int length) {
  486. int i = 0;
  487. char * cast_0 = (char *) memory;
  488. char * cast_1 = (char *) source;
  489. fatal_failure (memory == NULL, "memory_compare: Memory is null pointer.");
  490. fatal_failure (source == NULL, "memory_compare: Source is null pointer.");
  491. if (length <= 0) {
  492. return (-1);
  493. }
  494. for (i = 0; (cast_0 [i] != '\0') && (cast_1 [i] != '\0'); ++i) {
  495. if (cast_0 [i] != cast_1 [i]) {
  496. return (0);
  497. }
  498. }
  499. return (1);
  500. }
  501. void memory_copy (void * memory, void * source, int length) {
  502. int i = 0;
  503. char * cast_0 = (char *) memory;
  504. char * cast_1 = (char *) source;
  505. fatal_failure (memory == NULL, "memory_copy: Memory is null pointer.");
  506. fatal_failure (source == NULL, "memory_copy: Source is null pointer.");
  507. if (length <= 0) {
  508. return;
  509. }
  510. for (i = 0; i != length; ++i) {
  511. cast_0 [i] = cast_1 [i];
  512. }
  513. }
  514. void terminal_clear (void) {
  515. echo ("\033[2J\033[H");
  516. }
  517. void terminal_colour (int colour, int effect) {
  518. char format [8] = "\033[ ;3 m";
  519. format [2] = (char) (effect % EFFECT_COUNT) + '0';
  520. format [5] = (char) (colour % COLOUR_COUNT) + '0';
  521. echo (format);
  522. }
  523. void terminal_cancel (void) {
  524. echo ("\033[0m");
  525. }
  526. void terminal_show_cursor (int show) {
  527. if (show != 0) {
  528. echo ("\033[?25h");
  529. } else {
  530. echo ("\033[?25l");
  531. }
  532. }
  533. int encode_byte (char * byte) {
  534. int encode = 0;
  535. fatal_failure (character_is_hexadecimal (byte [0]) == 0, "encode_byte: Upper byte character is not hexadecimal digit.");
  536. fatal_failure (character_is_hexadecimal (byte [1]) == 0, "encode_byte: Lower byte character is not hexadecimal digit.");
  537. encode = ((byte [0] - (character_is_digit (byte [0]) ? ('0') : ('A' - 10))) << 4) | (byte [1] - (character_is_digit (byte [1]) ? ('0') : ('A' - 10)));
  538. return (encode);
  539. }
  540. char * decode_byte (int byte) {
  541. char * decode = " ";
  542. fatal_failure ((byte <= -1) || (byte >= 256), "decode_byte: Byte is out of range.");
  543. decode [0] = byte / 16;
  544. decode [1] = byte % 16;
  545. return (decode);
  546. }
  547. #endif