2023-11-07 10:14:07 -05:00
/*
Copyright ( c ) 2023 : Ognjen ' xolatile ' Milan Robovic
Xhartae is free software ! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation .
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 .
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 .
*/
# ifndef CHAPTER_1_SOURCE
# define CHAPTER_1_SOURCE
2023-11-09 09:41:53 -05:00
# include "chapter_1.h"
2023-11-09 19:01:22 -05:00
/*
In functions ' character_is_uppercase ' , ' character_is_lowercase ' and ' character_is_digit ' , we use characters that are in certain range on ASCII table , which we ' ll show just below .
So , it ' s safe to use ' > = ' and ' < = ' operators , but in other cases , we want to compare them selectively , and for simplicity we use function ' character_compare_array ' . . . Here ' s how
ASCII table looks like , I don ' t like encodings like UTF - 8 and others , so neither should you . We ' ll also write a subprogram that prints this to terminal or graphical window .
ASCII table :
_______________________________________________________________________________________________________________________________________________________________
2023-11-10 06:24:57 -05:00
| _0B______ | _0O__ | _0D__ | _0X_ | _SYM_ | _Full_name____________________________________ | _0B______ | _0O__ | _0D__ | _0X_ | _SYM_ | _Full_name____________________________________ |
2023-11-09 19:01:22 -05:00
| | |
| 0000000 | 000 | 0 | 00 | NUL | Null | 0000001 | 001 | 1 | 01 | SOH | Start of heading |
| 0000010 | 002 | 2 | 02 | STX | Start of text | 0000011 | 003 | 3 | 03 | ETX | End of text |
| 0000100 | 004 | 4 | 04 | EOT | End of transmission | 0000101 | 005 | 5 | 05 | ENQ | Enquiry |
| 0000110 | 006 | 6 | 06 | ACK | Acknowledge | 0000111 | 007 | 7 | 07 | BEL | Bell |
| 0001000 | 010 | 8 | 08 | BS | Backspace | 0001001 | 011 | 9 | 09 | HT | Horizontal tab |
| 0001010 | 012 | 10 | 0 A | LF | Line feed | 0001011 | 013 | 11 | 0 B | VT | Vertical tab |
| 0001100 | 014 | 12 | 0 C | FF | Form feed | 0001101 | 015 | 13 | 0 D | CR | Carriage return |
| 0001110 | 016 | 14 | 0 E | SO | Shift out | 0001111 | 017 | 15 | 0F | SI | Shift in |
| 0010000 | 020 | 16 | 10 | DLE | Data link escape | 0010001 | 021 | 17 | 11 | DC1 | Device control 1 |
| 0010010 | 022 | 18 | 12 | DC2 | Device control 2 | 0010011 | 023 | 19 | 13 | DC3 | Device control 3 |
| 0010100 | 024 | 20 | 14 | DC4 | Device control 4 | 0010101 | 025 | 21 | 15 | NAK | Negative acknowledge |
| 0010110 | 026 | 22 | 16 | SYN | Synchronous idle | 0010111 | 027 | 23 | 17 | ETB | End transmission block |
| 0011000 | 030 | 24 | 18 | CAN | Cancel | 0011001 | 031 | 25 | 19 | EM | End of medium |
| 0011010 | 032 | 26 | 1 A | SUB | Substitute | 0011011 | 033 | 27 | 1 B | ESC | Escape |
| 0011100 | 034 | 28 | 1 C | FS | File separator | 0011101 | 035 | 29 | 1 D | GS | Group separator |
| 0011110 | 036 | 30 | 1 E | RS | Record separator | 0011111 | 037 | 31 | 1F | US | Unit separator |
| 0100000 | 040 | 32 | 20 | | Space | 0100001 | 041 | 33 | 21 | ! | Exclamation mark |
| 0100010 | 042 | 34 | 22 | " | Speech mark | 0100011 | 043 | 35 | 23 | # | Number sign |
| 0100100 | 044 | 36 | 24 | $ | Dollar sign | 0100101 | 045 | 37 | 25 | % | Percent |
| 0100110 | 046 | 38 | 26 | & | Ampersand | 0100111 | 047 | 39 | 27 | ' | Quote |
| 0101000 | 050 | 40 | 28 | ( | Open parenthesis | 0101001 | 051 | 41 | 29 | ) | Close parenthesis |
| 0101010 | 052 | 42 | 2 A | * | Asterisk | 0101011 | 053 | 43 | 2 B | + | Plus |
| 0101100 | 054 | 44 | 2 C | , | Comma | 0101101 | 055 | 45 | 2 D | - | Minus |
| 0101110 | 056 | 46 | 2 E | . | Period | 0101111 | 057 | 47 | 2F | / | Slash |
| 0110000 | 060 | 48 | 30 | 0 | Zero | 0110001 | 061 | 49 | 31 | 1 | One |
| 0110010 | 062 | 50 | 32 | 2 | Two | 0110011 | 063 | 51 | 33 | 3 | Three |
| 0110100 | 064 | 52 | 34 | 4 | Four | 0110101 | 065 | 53 | 35 | 5 | Five |
| 0110110 | 066 | 54 | 36 | 6 | Six | 0110111 | 067 | 55 | 37 | 7 | Seven |
| 0111000 | 070 | 56 | 38 | 8 | Eight | 0111001 | 071 | 57 | 39 | 9 | Nine |
| 0111010 | 072 | 58 | 3 A | : | Colon | 0111011 | 073 | 59 | 3 B | ; | Semicolon |
| 0111100 | 074 | 60 | 3 C | < | Open angled bracket | 0111101 | 075 | 61 | 3 D | = | Equal |
| 0111110 | 076 | 62 | 3 E | > | Close angled bracket | 0111111 | 077 | 63 | 3F | ? | Question mark |
| 1000000 | 100 | 64 | 40 | @ | At sign | 1000001 | 101 | 65 | 41 | A | Uppercase A |
| 1000010 | 102 | 66 | 42 | B | Uppercase B | 1000011 | 103 | 67 | 43 | C | Uppercase C |
| 1000100 | 104 | 68 | 44 | D | Uppercase D | 1000101 | 105 | 69 | 45 | E | Uppercase E |
| 1000110 | 106 | 70 | 46 | F | Uppercase F | 1000111 | 107 | 71 | 47 | G | Uppercase G |
| 1001000 | 110 | 72 | 48 | H | Uppercase H | 1001001 | 111 | 73 | 49 | I | Uppercase I |
| 1001010 | 112 | 74 | 4 A | J | Uppercase J | 1001011 | 113 | 75 | 4 B | K | Uppercase K |
| 1001100 | 114 | 76 | 4 C | L | Uppercase L | 1001101 | 115 | 77 | 4 D | M | Uppercase M |
| 1001110 | 116 | 78 | 4 E | N | Uppercase N | 1001111 | 117 | 79 | 4F | O | Uppercase O |
| 1010000 | 120 | 80 | 50 | P | Uppercase P | 1010001 | 121 | 81 | 51 | Q | Uppercase Q |
| 1010010 | 122 | 82 | 52 | R | Uppercase R | 1010011 | 123 | 83 | 53 | S | Uppercase S |
| 1010100 | 124 | 84 | 54 | T | Uppercase T | 1010101 | 125 | 85 | 55 | U | Uppercase U |
| 1010110 | 126 | 86 | 56 | V | Uppercase V | 1010111 | 127 | 87 | 57 | W | Uppercase W |
| 1011000 | 130 | 88 | 58 | X | Uppercase X | 1011001 | 131 | 89 | 59 | Y | Uppercase Y |
| 1011010 | 132 | 90 | 5 A | Z | Uppercase Z | 1011011 | 133 | 91 | 5 B | [ | Opening bracket |
| 1011100 | 134 | 92 | 5 C | \ | Backslash | 1011101 | 135 | 93 | 5 D | ] | Closing bracket |
| 1011110 | 136 | 94 | 5 E | ^ | Caret | 1011111 | 137 | 95 | 5F | _ | Underscore |
| 1100000 | 140 | 96 | 60 | ` | Grave | 1100001 | 141 | 97 | 61 | a | Lowercase a |
| 1100010 | 142 | 98 | 62 | b | Lowercase b | 1100011 | 143 | 99 | 63 | c | Lowercase c |
| 1100100 | 144 | 100 | 64 | d | Lowercase d | 1100101 | 145 | 101 | 65 | e | Lowercase e |
| 1100110 | 146 | 102 | 66 | f | Lowercase f | 1100111 | 147 | 103 | 67 | g | Lowercase g |
| 1101000 | 150 | 104 | 68 | h | Lowercase h | 1101001 | 151 | 105 | 69 | i | Lowercase i |
| 1101010 | 152 | 106 | 6 A | j | Lowercase j | 1101011 | 153 | 107 | 6 B | k | Lowercase k |
| 1101100 | 154 | 108 | 6 C | l | Lowercase l | 1101101 | 155 | 109 | 6 D | m | Lowercase m |
| 1101110 | 156 | 110 | 6 E | n | Lowercase n | 1101111 | 157 | 111 | 6F | o | Lowercase o |
| 1110000 | 160 | 112 | 70 | p | Lowercase p | 1110001 | 161 | 113 | 71 | q | Lowercase q |
| 1110010 | 162 | 114 | 72 | r | Lowercase r | 1110011 | 163 | 115 | 73 | s | Lowercase s |
| 1110100 | 164 | 116 | 74 | t | Lowercase t | 1110101 | 165 | 117 | 75 | u | Lowercase u |
| 1110110 | 166 | 118 | 76 | v | Lowercase v | 1110111 | 167 | 119 | 77 | w | Lowercase w |
| 1111000 | 170 | 120 | 78 | x | Lowercase x | 1111001 | 171 | 121 | 79 | y | Lowercase y |
| 1111010 | 172 | 122 | 7 A | z | Lowercase z | 1111011 | 173 | 123 | 7 B | { | Opening brace |
| 1111100 | 174 | 124 | 7 C | | | Vertical bar | 1111101 | 175 | 125 | 7 D | } | Closing brace |
| 1111110 | 176 | 126 | 7 E | ~ | Tilde | 1111111 | 177 | 127 | 7F | DEL | Delete |
| _______________________________________________________________________________ | _______________________________________________________________________________ |
You can see that values of ' A ' . . . ' Z ' , ' a ' . . . ' z ' and ' 0 ' . . . ' 9 ' are sequential , but symbols and " system " characters are mixed up .
*/
2023-11-09 07:33:47 -05:00
int character_is_uppercase ( char character ) {
return ( ( int ) ( ( character > = ' A ' ) & & ( character < = ' Z ' ) ) ) ;
}
int character_is_lowercase ( char character ) {
return ( ( int ) ( ( character > = ' a ' ) & & ( character < = ' z ' ) ) ) ;
}
int character_is_digit ( char character ) {
return ( ( int ) ( ( character > = ' 0 ' ) & & ( character < = ' 9 ' ) ) ) ;
}
2023-11-09 19:01:22 -05:00
int character_is_blank ( char character ) { // Standard implementation also considers vertical tab and form feed as blank, we don't...
2023-11-09 09:41:53 -05:00
return ( ( int ) ( ( character = = ' ' ) | | ( character = = CHARACTER_TAB_HORIZONTAL ) | | ( character = = CHARACTER_CARRIAGE_RETURN ) | | ( character = = CHARACTER_LINE_FEED ) ) ) ;
// If you like smaller line length limit, you can align it like this:
// return ((character == ' ')
// || (character == CHARACTER_TAB_HORIZONTAL)
// || (character == CHARACTER_CARRIAGE_RETURN)
// || (character == CHARACTER_LINE_FEED));
// Or:
// return ((character == ' ') ||
// (character == CHARACTER_TAB_HORIZONTAL) ||
// (character == CHARACTER_CARRIAGE_RETURN) ||
// (character == CHARACTER_LINE_FEED));
// Or even use literal characters:
// return ((character == ' ') ||
// (character == '\t') ||
// (character == '\r') ||
// (character == '\n'));
2023-11-09 07:33:47 -05:00
}
2023-11-09 19:01:22 -05:00
int character_is_alpha ( char character ) { // Returns TRUE / 1 or FALSE / 0 depending on if the character is either uppercase or lowercase.
2023-11-09 07:33:47 -05:00
return ( ( character_is_uppercase ( character ) ! = 0 ) | | ( character_is_lowercase ( character ) ! = 0 ) ) ;
}
2023-11-09 19:01:22 -05:00
int character_is_symbol ( char character ) { // Returns TRUE / 1 if character is one of the characters in that string (array of characters), otherwise it returns FALSE / 0.
2023-11-09 07:33:47 -05:00
return ( character_compare_array ( character , " ~!@#$%^&*()+{}|: \" <>?`-=[] \\ ;',./ " ) ) ;
}
2023-11-09 19:01:22 -05:00
int character_is_visible ( char character ) { // This is visible (printable) character range, and space is included in there.
2023-11-09 07:33:47 -05:00
return ( ( int ) ( ( character > = ' ' ) & & ( character < = ' ~ ' ) ) ) ;
}
2023-11-09 19:01:22 -05:00
int character_is_invisible ( char character ) { // If character is not visible, then guess what? It's invisible.
return ( character_is_visible ( character ) = = FALSE ) ;
2023-11-09 07:33:47 -05:00
}
2023-11-09 19:01:22 -05:00
int character_is_escape ( char character ) { // We might use this function...
2023-11-09 13:22:59 -05:00
return ( ( int ) ( character = = CHARACTER_ESCAPE ) ) ;
2023-11-09 07:33:47 -05:00
}
2023-11-09 19:01:22 -05:00
int character_is_underscore ( char character ) { // I don't even know if I'll ever use this one, we'll see, I'm in the process of writing this "book"...
2023-11-09 07:33:47 -05:00
return ( ( int ) ( character = = ' _ ' ) ) ;
}
2023-11-09 19:01:22 -05:00
int character_is_hexadecimal ( char character ) { // Same as function 'character_is_symbol', but for hexadecimal digits.
2023-11-09 07:33:47 -05:00
return ( character_compare_array ( character , " 0123456789ABCDEF " ) ) ;
}
2023-11-10 06:24:57 -05:00
/*
Now , we can see how function ' character_compare_array ' was implemented , but know that it could be even shorter , like you see below . However , I really think it ' s for the best to
use curly and round braces , when even the compiler won ' t warn about them . You can easily see the scope of something if you have a text editor capable of highlighting matching
braces , and almost all of them have that feature .
@ C
int character_compare_array ( char character , char * character_array ) {
for ( ; * character_array ! = CHARACTER_NULL ; + + character_array )
if ( character = = * character_array )
return ( TRUE ) ;
return ( FALSE ) ;
}
@
*/
2023-11-09 19:01:22 -05:00
int character_compare_array ( char character , char * character_array ) { // I didn't use name "string", but "character_array", to explicitly show the intention of argument.
int offset ;
2023-11-09 07:33:47 -05:00
2023-11-09 19:01:22 -05:00
for ( offset = 0 ; offset ! = string_length ( character_array ) ; + + offset ) { // We iterate through string (character array!) and return TRUE / 1 if we found it.
if ( character = = character_array [ offset ] ) { // If we don't find it in that string, we return FALSE / 0 since it's not there.
return ( TRUE ) ; // Note that we could do this without the variable 'offset', similar to string functions.
2023-11-09 07:33:47 -05:00
}
}
2023-11-09 19:01:22 -05:00
return ( FALSE ) ;
2023-11-09 07:33:47 -05:00
}
2023-11-09 13:22:59 -05:00
int file_open ( char * name , int mode ) {
int descriptor = - 1 ;
fatal_failure ( name = = NULL , " file_open: Failed to open file, name is null pointer. " ) ;
descriptor = open ( name , mode ) ;
fatal_failure ( descriptor = = - 1 , " file_open: Failed to open file, function open returned invalid descriptor. " ) ;
return ( descriptor ) ;
}
int file_close ( int file ) {
fatal_failure ( file = = - 1 , " file_close: Failed to close file, invalid file descriptor. " ) ;
fatal_failure ( close ( file ) = = - 1 , " file_close: Failed to close file, function close returned invalid code. " ) ;
return ( - 1 ) ;
}
void file_read ( int file , void * data , int size ) {
fatal_failure ( file = = - 1 , " file_read: Failed to read from file, invalid descriptor. " ) ;
fatal_failure ( data = = NULL , " file_read: Failed to read from file, data is null pointer. " ) ;
fatal_failure ( size = = 0 , " file_read: Failed to read from file, size is zero. " ) ;
( void ) read ( file , data , ( unsigned long int ) size ) ;
}
void file_write ( int file , void * data , int size ) {
fatal_failure ( file = = - 1 , " file_write: Failed to write to file, invalid descriptor. " ) ;
fatal_failure ( data = = NULL , " file_write: Failed to write to file, data is null pointer. " ) ;
fatal_failure ( size = = 0 , " file_write: Failed to write to file, size is zero. " ) ;
( void ) write ( file , data , ( unsigned long int ) size ) ;
}
int file_seek ( int file , int whence ) {
fatal_failure ( file = = - 1 , " file_seek: Failed to seek in file, invalid descriptor. " ) ;
return ( ( int ) lseek ( file , 0 , whence ) ) ;
}
int file_size ( char * name ) {
int size = - 1 ;
int file = - 1 ;
file = file_open ( name , O_RDONLY ) ;
size = lseek ( file , 0 , SEEK_END ) ;
fatal_failure ( size = = - 1 , " file_size: Failed to get size of file, invalid file size. " ) ;
file = file_close ( file ) ;
return ( size ) ;
}
int file_type ( char * name ) {
char * file_type_data [ FILE_TYPE_COUNT ] = {
" .txt " , " .s " , " .fasm " , " .gasm " , " .nasm " , " .yasm " , " .c " , " .h " ,
" .adb " , " .ads " , " .cpp " , " .hpp "
} ;
int type = 0 ;
while ( * name ! = ' . ' ) {
+ + name ;
}
for ( type = 0 ; type ! = FILE_TYPE_COUNT ; + + type ) {
if ( string_compare ( name , file_type_data [ type ] ) ! = 0 ) {
return ( type ) ;
}
}
return ( - 1 ) ;
}
void * file_record ( char * name ) {
int file = - 1 ;
int size = - 1 ;
char * data = NULL ;
fatal_failure ( name = = NULL , " file_import: Failed to import file, name is null pointer. " ) ;
file = file_open ( name , O_RDONLY ) ;
size = file_size ( name ) ;
data = allocate ( size ) ;
file_read ( file , data , size ) ;
file = file_close ( file ) ;
return ( data ) ;
}
2023-11-07 10:14:07 -05:00
# endif