forked from xolatile/xhartae
More comments...
This commit is contained in:
parent
f1031f5360
commit
839f92f40f
@ -50,7 +50,7 @@ void echo (char * string) {
|
||||
}
|
||||
|
||||
void fatal_failure (int condition, char * message) { // We use this function to abort the program if condition is met and to print the message.
|
||||
if (condition != 0) { // If the variable 'condition' is not equal to 0, we execute the code in curly braces.
|
||||
if (condition == FALSE) { // If the variable 'condition' is not equal to 0, we execute the code in curly braces.
|
||||
echo ("[\033[1;31mExiting\033[0m] "); // Simply printing the message using our 'echo' function, but we also use some colours, more on that later.
|
||||
echo (message); // Also, notice how "this or that" is implicity 'char *' type... Maybe it's too early to explain it at this point.
|
||||
echo ("\n"); // This will only print a new line, we'll see how to use it later.
|
||||
@ -82,7 +82,7 @@ char * data = NULL;
|
||||
data = malloc (20 * sizeof (* data)); // Allocates 20 bytes of memory for 'data'.
|
||||
data = calloc (20, sizeof (* data)); // Allocates 20 bytes also, but initializes them to 0 value.
|
||||
data = realloc (data, 20 * sizeof (* data)); // When 'data' is null pointer, it will be same as 'malloc', else it will reallocate more memory (for correct usage).
|
||||
|
||||
// Also, it's best to just use 'calloc', but it complicates some other tasks.
|
||||
free (data); // Deallocates memory, we'll talk about "double free" later.
|
||||
@
|
||||
*/
|
||||
@ -120,36 +120,79 @@ void * deallocate (void * data) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
This program is intended to be a book-like guide for this source code, which is also a book. We'll deal with strings a lot, and they're a good example of code formatting which is
|
||||
the main topic of chapter zero. In function 'string_length' we have for loop without a body, some people prefer to put '{}' or ';' in same or next line, to express the intention
|
||||
that the loop shouldn't have a body (code block {}). I just put ';' on the same line. Also, functions 'string_*' could depend on functions 'string_*_limit', but we won't do that
|
||||
now, and since we've already declared them in header file "chapter_0.h" we can define them and call them in whatever order we want. Nice.
|
||||
|
||||
@C
|
||||
// Simple example of how we could make it dependable on 'string_*_limit' function...
|
||||
|
||||
int string_compare (char * string_0, char * string_1) {
|
||||
return (string_0, string_1, string_length (string_0));
|
||||
}
|
||||
@
|
||||
*/
|
||||
|
||||
int string_length (char * string) {
|
||||
int length;
|
||||
|
||||
if (string == NULL) {
|
||||
return (0);
|
||||
}
|
||||
fatal_failure (string == NULL, "string_length: String is null pointer.");
|
||||
|
||||
for (length = 0; string [length] != '\0'; ++length);
|
||||
for (length = 0; string [length] != CHARACTER_NULL; ++length); // Since in C, strings are null terminated, looping until we see null character is strings' length.
|
||||
|
||||
return (length);
|
||||
}
|
||||
|
||||
/*
|
||||
Now, I've implemented "unlimited" versions of string comparison, copying and concatenation different from "limited" versions. They correspond with standard library functions
|
||||
'strcmp', 'strcpy', 'strcat', 'strncmp', 'strncpy' and 'strncat' found in header file <string.h>. In "unlimited" versions, I rely on the fact that we want to apply the operation
|
||||
on entire strings, that those strings are null terminated and I used that in my advantage. For example, function 'string_compare' could be something like this:
|
||||
|
||||
@C
|
||||
int string_compare (char * string_0, char * string_1) {
|
||||
if (string_length (string_0) != string_length (string_1)) {
|
||||
return (0);
|
||||
} else {
|
||||
return (string_compare_limit (string_0, string_1, string_length (string_0)));
|
||||
int offset;
|
||||
|
||||
fatal_failure (string_0 == NULL, "string_compare: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_compare: Source string is null pointer.");
|
||||
|
||||
for (offset = 0; (string_0 [offset] != CHARACTER_NULL) && (string_1 [offset] != CHARACTER_NULL); ++offset) {
|
||||
if (string_0 [offset] != string_1 [offset]) {
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
@
|
||||
|
||||
And I used this approach below to show that you can solve the problem using different solutions...
|
||||
*/
|
||||
|
||||
int string_compare (char * string_0, char * string_1) {
|
||||
fatal_failure (string_0 == NULL, "string_compare: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_compare: Source string is null pointer.");
|
||||
|
||||
for (; (* string_0 != CHARACTER_NULL) && (* string_1 != CHARACTER_NULL); ++string_0, ++string_1) {
|
||||
if (* string_0 != * string_1) {
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
char * string_copy (char * string_0, char * string_1) {
|
||||
int i = 0;
|
||||
|
||||
fatal_failure (string_0 == NULL, "string_copy: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_copy: Source string is null pointer.");
|
||||
|
||||
for (i = 0; i != string_length (string_1) + 1; ++i) {
|
||||
string_0 [i] = string_1 [i];
|
||||
for (; * string_1 != CHARACTER_NULL; ++string_0, ++string_1) {
|
||||
* string_0 = * string_1;
|
||||
}
|
||||
|
||||
* string_0 = * string_1; // Copying null termination, since the loop stopped on that condition.
|
||||
|
||||
return (string_0);
|
||||
}
|
||||
|
||||
@ -159,66 +202,60 @@ char * string_concatenate (char * string_0, char * string_1) {
|
||||
|
||||
string_0 += string_length (string_0);
|
||||
|
||||
while (* string_1 != '\0') {
|
||||
* string_0++ = * string_1++;
|
||||
/*++string_0;
|
||||
++string_1;*/
|
||||
for (; * string_1 != CHARACTER_NULL; ++string_0, ++string_1) {
|
||||
* string_0 = * string_1;
|
||||
}
|
||||
|
||||
* string_0 = '\0';
|
||||
* string_0 = CHARACTER_NULL;
|
||||
|
||||
return (string_0);
|
||||
}
|
||||
|
||||
int string_compare_limit (char * string_0, char * string_1, int limit) {
|
||||
int i = 0;
|
||||
int offset;
|
||||
|
||||
fatal_failure (string_0 == NULL, "string_compare_limit: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_compare_limit: Source string is null pointer.");
|
||||
|
||||
for (i = 0; i != limit; ++i) {
|
||||
if (string_0 [i] != string_1 [i]) {
|
||||
return (0);
|
||||
for (offset = 0; offset != limit; ++offset) {
|
||||
if (string_0 [offset] != string_1 [offset]) {
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return (1);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
char * string_copy_limit (char * string_0, char * string_1, int limit) {
|
||||
int i = 0;
|
||||
int offset;
|
||||
|
||||
fatal_failure (string_0 == NULL, "string_copy_limit: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_copy_limit: Source string is null pointer.");
|
||||
|
||||
if (limit <= 0) {
|
||||
if ((limit <= 0) || (string_1 == NULL)) {
|
||||
return (string_0);
|
||||
}
|
||||
|
||||
for (i = 0; i != limit; ++i) {
|
||||
string_0 [i] = string_1 [i];
|
||||
for (offset = 0; offset != limit; ++offset) {
|
||||
string_0 [offset] = string_1 [offset];
|
||||
}
|
||||
|
||||
return (string_0);
|
||||
}
|
||||
|
||||
char * string_concatenate_limit (char * string_0, char * string_1, int limit) {
|
||||
int i = 0;
|
||||
int length_0 = 0;
|
||||
int length_1 = 0;
|
||||
int offset, length_0, length_1;
|
||||
|
||||
fatal_failure (string_0 == NULL, "string_concatenate_limit: Destination string is null pointer.");
|
||||
fatal_failure (string_1 == NULL, "string_concatenate_limit: Source string is null pointer.");
|
||||
|
||||
if (limit <= 0) {
|
||||
if ((limit <= 0) || (string_1 == NULL)) {
|
||||
return (string_0);
|
||||
}
|
||||
|
||||
length_0 = string_length (string_0);
|
||||
length_1 = string_length (string_1);
|
||||
|
||||
for (i = 0; (i != length_1) && (i != limit); ++i) {
|
||||
string_0 [length_0 + i] = string_1 [i];
|
||||
for (offset = 0; (offset != length_1) && (offset != limit); ++offset) {
|
||||
string_0 [length_0 + offset] = string_1 [offset];
|
||||
}
|
||||
|
||||
return (string_0);
|
||||
|
@ -167,14 +167,9 @@ eye on how are they aligned and named. I'll reimplement some standard functions,
|
||||
#define SIGNAL_ARROW_RIGHT (0X435B1B)
|
||||
#define SIGNAL_ARROW_LEFT (0X445B1B)
|
||||
|
||||
enum { // I like to align enumerations with 10, 20 or 40 characters per name, and optionally use NAME_ as prefix and NAME_COUNT as last element.
|
||||
EFFECT_NORMAL, EFFECT_BOLD, EFFECT_ITALIC, EFFECT_UNDERLINE, EFFECT_BLINK, EFFECT_REVERSE,
|
||||
EFFECT_COUNT
|
||||
};
|
||||
|
||||
enum { // Because of text auto-completition, it's always easy to find what I want, or to use NAME_COUNT in arrays. In some cases, order matters!
|
||||
COLOUR_GREY, COLOUR_RED, COLOUR_GREEN, COLOUR_YELLOW, COLOUR_BLUE, COLOUR_PINK, COLOUR_CYAN, COLOUR_WHITE,
|
||||
COLOUR_COUNT
|
||||
enum { // This is completely unnecesary, but I don't care, it's a good showcase how boolean type can work, true is 1 and false is 0.
|
||||
FALSE,
|
||||
TRUE
|
||||
};
|
||||
|
||||
enum { // This is also one of my preferences, to use CHARACTER_NULL or CHARACTER_LINE_FEED instead of '\0' or '\n' in special (non-string) cases.
|
||||
@ -189,6 +184,16 @@ enum { // This is also one of my preferences, to use CHARACTER_NULL or CHARACTER
|
||||
CHARACTER_COUNT
|
||||
};
|
||||
|
||||
enum { // I like to align enumerations with 10, 20 or 40 characters per name, and optionally use NAME_ as prefix and NAME_COUNT as last element.
|
||||
EFFECT_NORMAL, EFFECT_BOLD, EFFECT_ITALIC, EFFECT_UNDERLINE, EFFECT_BLINK, EFFECT_REVERSE,
|
||||
EFFECT_COUNT
|
||||
};
|
||||
|
||||
enum { // Because of text auto-completition, it's always easy to find what I want, or to use NAME_COUNT in arrays. In some cases, order matters!
|
||||
COLOUR_GREY, COLOUR_RED, COLOUR_GREEN, COLOUR_YELLOW, COLOUR_BLUE, COLOUR_PINK, COLOUR_CYAN, COLOUR_WHITE,
|
||||
COLOUR_COUNT
|
||||
};
|
||||
|
||||
extern void in (void * data, int size); // We'll use these functions later as core standard input/output functions.
|
||||
extern void out (void * data, int size);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user