Initial Commit
This commit is contained in:
131
OU4/src/list/list_mwe1i.c
Normal file
131
OU4/src/list/list_mwe1i.c
Normal file
@@ -0,0 +1,131 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <list.h>
|
||||
|
||||
/*
|
||||
* Minimum working example for list.c that shows how the internal
|
||||
* structure of a list can be visualized. In this version, the list
|
||||
* "borrows" the payload memory, i.e., the user of the list is
|
||||
* responsible for deallocating the payload memory. See list_mwe2i.c
|
||||
* for a version where the list takes over the responsibility.
|
||||
*
|
||||
* Authors: Niclas Borlin (niclas@cs.umu.se)
|
||||
*
|
||||
* Version information:
|
||||
* v1.0 2024-03-14: First public version.
|
||||
* v1.1 2024-03-15: Moved printout of dot instructions to separate function.
|
||||
*/
|
||||
|
||||
#define VERSION "v1.1"
|
||||
#define VERSION_DATE "2024-03-15"
|
||||
|
||||
// Integers are stored via int pointers stored as void pointers.
|
||||
// Convert the given pointer and print the dereferenced value.
|
||||
void print_int(const void *data)
|
||||
{
|
||||
const int *v = data;
|
||||
printf("%d", *v);
|
||||
}
|
||||
|
||||
// Create a dynamic copy of the integer i.
|
||||
int *int_create(int i)
|
||||
{
|
||||
// Allocate memory for an integer and set the value
|
||||
int *v = malloc(sizeof(*v));
|
||||
*v = i;
|
||||
return v;
|
||||
}
|
||||
|
||||
// Return the memory used by the integer.
|
||||
void int_kill(void *v)
|
||||
{
|
||||
int *p = v; // Convert to a readable pointer - useful in a debugger
|
||||
free(p);
|
||||
}
|
||||
|
||||
// Print cut lines before and after a call list_print_internal.
|
||||
void print_internal_with_cut_lines(const list *l, const char *desc)
|
||||
{
|
||||
// Internal counter that will be remembered between calls.
|
||||
|
||||
// Used to generate sequentially numbered -- CUT HERE -- marker lines
|
||||
// to enable automatic parsing of the output.
|
||||
static int cut = 1;
|
||||
|
||||
// Print starting marker line.
|
||||
printf("\n--- START CUT HERE %d ---\n", cut);
|
||||
|
||||
// Call the internal print function to get the actual dot code.
|
||||
list_print_internal(l, print_int, desc, 0);
|
||||
|
||||
// Print ending marker line
|
||||
printf("--- END CUT HERE %d ---\n\n", cut);
|
||||
|
||||
// Increment the cut number. Will be remembered next time the
|
||||
// function is called since cut is a static variable.
|
||||
cut++;
|
||||
}
|
||||
|
||||
// Print a message with intructions how to use the dot output. prog is
|
||||
// the name of the executable.
|
||||
void print_dot_usage(char *prog)
|
||||
{
|
||||
printf("\nGenerate dot code to visualize internal structure with GraphViz. ");
|
||||
printf("Use\n\n%s ", prog);
|
||||
printf("| sed -n '/START CUT HERE X/,/END CUT HERE X/{//!p}' | dot -Tsvg > /tmp/dot.svg\n\n");
|
||||
printf("to generate an svg file of cut X (replace X by the requested cut number).\n");
|
||||
printf("The generated file can then be visualized with\n\n");
|
||||
printf("firefox /tmp/dot.svg\n\n");
|
||||
printf("Use -Tpng to generate a .png file instead. "
|
||||
"See graphviz.org and %s for documentation.\n", __FILE__);
|
||||
|
||||
printf("\n--- Start of normal output ---\n\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("%s, %s %s: Create integer list without kill_function.\n",
|
||||
__FILE__, VERSION, VERSION_DATE);
|
||||
printf("Code base version %s (%s).\n\n", CODE_BASE_VERSION, CODE_BASE_RELEASE_DATE);
|
||||
|
||||
print_dot_usage(argv[0]);
|
||||
|
||||
// Create the list.
|
||||
list *l = list_empty(NULL);
|
||||
|
||||
printf("Empty list from the outside:\n");
|
||||
list_print(l, print_int);
|
||||
print_internal_with_cut_lines(l, "Empty list showing the internal structure");
|
||||
|
||||
// Insert the value 5 first in the list.
|
||||
list_insert(l, int_create(5), list_first(l));
|
||||
// Insert the value 8 last in the list.
|
||||
list_insert(l, int_create(8), list_end(l));
|
||||
// Insert the value 2 at the second position in the list.
|
||||
list_insert(l, int_create(2), list_next(l, list_first(l)));
|
||||
|
||||
printf("List from the outside after inserting 3 values:\n");
|
||||
list_print(l, print_int);
|
||||
const char *long_desc = __FILE__
|
||||
": Internal structure of the List after inserting 3 values.\n"
|
||||
"Red lines are used for the list payload.\n\n"
|
||||
"The dashed red lines indicate that the payload memory is\n"
|
||||
"BORROWED by the list, i.e., the payload\n"
|
||||
"memory will NOT be deallocated by the list.\n\n"
|
||||
"See list_mwe2i for a list example\nthat owns the payload memory.";
|
||||
print_internal_with_cut_lines(l, long_desc);
|
||||
|
||||
// Empty the list.
|
||||
while (!list_is_empty(l)) {
|
||||
list_pos p=list_first(l);
|
||||
int *v=list_inspect(l,p);
|
||||
int_kill(v);
|
||||
list_remove(l,p);
|
||||
}
|
||||
// Done, kill the list.
|
||||
list_kill(l);
|
||||
|
||||
printf("\nNormal exit.\n\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user