Hi.

I want to learn C and to that effect I started
a first project of a program, Geomant.

The version-named file is the first version that
I both consider accomplished and bug-free.
(using clang on openbsd 7.1)

The geomant.c file is an attempt at improving the
code (mainly by declaring more variable locally)
that produces my first run-time bug instead of
a compiler warning or error.

Would you review part of whole of either file
and tell me what you think of my code ?

Thank you.

For more information on geomanteia, see:
http://naosofiakkhos.blogspot.com/2011/01/casting-of-shield-of-geomanteia.html
https://en.wikipedia.org/wiki/Geomantic_figures

--
Sylvain Saboua
from webmail
/*****************************************/
/*     Geomant : a basic implementation  */
/*  of the geomanteia intended as a first*/
/*  C training project                   */
/*  copyright © Sylvain Saboua    */
/*  <sylvain ! saboua (|) free ! fr>     */
/*****************************************/

# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <unistd.h>

char *txt_topic ; size_t txt_topic_size = 0UL ;

// arrays displaying which figure part the user is generating.
// used between the mantize() function that gathers/parses  user input,
// and generate() that generates the figures from it.
static char *mother_figures[] = { "1st", "2nd", "3rd", "4th" } ; int n_figure ;
static char *body_parts[] = { "head", "neck", "body", "feet" } ; int n_bodypart ;

// figures initialization (all 15 figures)
char *figures[15][4] = {
	// mothers
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},

	// daughters
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},

	// nieces
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},

	// witnesses & judge
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "}
} ;

// used to temporarily store user input, which may be anything other than \0 and \n
char *txt_raw_scrap = NULL ;
size_t txt_raw_scrap_size = 0UL ;


/*

	"mantize" : input fuction

 This function gathers a string of user input
 and returns a 0 or 1 for the evenness or
 oddity of the number of characters. It is called
 in a sequence by the next function to generate
 the figures one by one.

*/

int mantize ( int n_bodypart, int n_figure ) {
	printf ( "Hold or repeatedly press a key or keys to generate the %s of the %s mother, then press Enter:\n",
		body_parts[n_bodypart], mother_figures[n_figure] ) ;
	getline ( &txt_raw_scrap, &txt_raw_scrap_size, stdin ) ; 
	return ( ( strlen ( txt_raw_scrap ) -1 ) % 2 ) ; // substracting 1 as the \n character
}


/*
 
	"generate" fuction:

 This function takes the cast result (being 0 or 1,
 odd or even) and use it to generate
 all 15 figures, from the mothers down to the
 daughters, nieces, witnesses and judge.

*/

int generate(){

	// generating the mothers
	for ( n_figure = 0 ; n_figure < 4 ; n_figure++ ) {
		for ( n_bodypart = 0 ; n_bodypart < 4 ; n_bodypart++ ) {
			figures[n_figure][n_bodypart] =
			(0 == mantize(n_bodypart, n_figure)) ? "* *" : " * " ;
			system("clear");
		}
	}
	
	//generating the four daughters from the four mothers

	figures[4][0] = figures[0][0] ;
	figures[4][1] = figures[1][0] ;
	figures[4][2] = figures[2][0] ;
	figures[4][3] = figures[3][0] ;
	
	figures[5][0] = figures[0][1] ;
	figures[5][1] = figures[1][1] ;
	figures[5][2] = figures[2][1] ;
	figures[5][3] = figures[3][1] ;
	
	figures[6][0] = figures[0][2] ;
	figures[6][1] = figures[1][2] ;
	figures[6][2] = figures[2][2] ;
	figures[6][3] = figures[3][2] ;
	
	figures[7][0] = figures[0][3] ;
	figures[7][1] = figures[1][3] ;
	figures[7][2] = figures[2][3] ;
	figures[7][3] = figures[3][3] ;
	
	// generating the nieces
	
	figures[8][0] = ( figures[0][0] == figures[1][0] ) ? "* *" : " * " ;
	figures[8][1] = ( figures[0][1] == figures[1][1] ) ? "* *" : " * " ;
	figures[8][2] = ( figures[0][2] == figures[1][2] ) ? "* *" : " * " ;
	figures[8][3] = ( figures[0][3] == figures[1][3] ) ? "* *" : " * " ;
	
	figures[9][0] = ( figures[2][0] == figures[3][0] ) ? "* *" : " * " ;
	figures[9][1] = ( figures[2][1] == figures[3][1] ) ? "* *" : " * " ;
	figures[9][2] = ( figures[2][2] == figures[3][2] ) ? "* *" : " * " ;
	figures[9][3] = ( figures[2][3] == figures[3][3] ) ? "* *" : " * " ;
	
	figures[10][0] = ( figures[4][0] == figures[5][0] ) ? "* *" : " * " ;
	figures[10][1] = ( figures[4][1] == figures[5][1] ) ? "* *" : " * " ;
	figures[10][2] = ( figures[4][2] == figures[5][2] ) ? "* *" : " * " ;
	figures[10][3] = ( figures[4][3] == figures[5][3] ) ? "* *" : " * " ;
	
	figures[11][0] = ( figures[6][0] == figures[7][0] ) ? "* *" : " * " ;
	figures[11][1] = ( figures[6][1] == figures[7][1] ) ? "* *" : " * " ;
	figures[11][2] = ( figures[6][2] == figures[7][2] ) ? "* *" : " * " ;
	figures[11][3] = ( figures[6][3] == figures[7][3] ) ? "* *" : " * " ;
	
	// generating the witnesses
	
	figures[12][0] = ( figures[8][0] == figures[9][0] ) ? "* *" : " * " ;
	figures[12][1] = ( figures[8][1] == figures[9][1] ) ? "* *" : " * " ;
	figures[12][2] = ( figures[8][2] == figures[9][2] ) ? "* *" : " * " ;
	figures[12][3] = ( figures[8][3] == figures[9][3] ) ? "* *" : " * " ;
	
	figures[13][0] = ( figures[10][0] == figures[11][0] ) ? "* *" : " * " ;
	figures[13][1] = ( figures[10][1] == figures[11][1] ) ? "* *" : " * " ;
	figures[13][2] = ( figures[10][2] == figures[11][2] ) ? "* *" : " * " ;
	figures[13][3] = ( figures[10][3] == figures[11][3] ) ? "* *" : " * " ;
	 
	//generating the judge

	figures[14][0] = ( figures[12][0] == figures[13][0] ) ? "* *" : " * " ;
	figures[14][1] = ( figures[12][1] == figures[13][1] ) ? "* *" : " * " ;
	figures[14][2] = ( figures[12][2] == figures[13][2] ) ? "* *" : " * " ;
	figures[14][3] = ( figures[12][3] == figures[13][3] ) ? "* *" : " * " ;
	
	return *figures[14][3] ;
}


/*

	"display" function:

 This function will display onscreen the final
 geomantic Shield for the given divination.
 The "-" & "|" characters are used for separation
 while the dots are displayed using "*"

*/

int main(){
	
	printf("What is the subject title of your enquiry ?\n");
	getline ( &txt_topic, &txt_topic_size, stdin ) ; 

	generate();
	
	printf ("\n    %s\n", txt_topic);
	printf ("  |-----------------------------------------|\n"); // top line
	
	// printing the first 8 figures (4 daughters & 4 mothers)
	printf ("  | %s  %s  %s  %s | %s  %s  %s  %s |\n"
		"  | %s  %s  %s  %s | %s  %s  %s  %s |\n"
		"  | %s  %s  %s  %s | %s  %s  %s  %s |\n"
		"  | %s  %s  %s  %s | %s  %s  %s  %s |\n",
		figures[7][0],figures[6][0],figures[5][0],figures[4][0],
		figures[3][0],figures[2][0],figures[1][0],figures[0][0],
		figures[7][1],figures[6][1],figures[5][1],figures[4][1],
		figures[3][1],figures[2][1],figures[1][1],figures[0][1],
		figures[7][2],figures[6][2],figures[5][2],figures[4][2],
		figures[3][2],figures[2][2],figures[1][2],figures[0][2],
		figures[7][3],figures[6][3],figures[5][3],figures[4][3],
		figures[3][3],figures[2][3],figures[1][3],figures[0][3]);
	printf ("  |-----------------------------------------|\n"); 
	
	// printing the four nieces
	printf ("  |    %s      %s    |    %s      %s    |\n"
		"  |    %s      %s    |    %s      %s    |\n"
		"  |    %s      %s    |    %s      %s    |\n"
		"  |    %s      %s    |    %s      %s    |\n",
		figures[11][0],figures[10][0],figures[9][0],figures[8][0],
		figures[11][1],figures[10][1],figures[9][1],figures[8][1],
		figures[11][2],figures[10][2],figures[9][2],figures[8][2],
		figures[11][3],figures[10][3],figures[9][3],figures[8][3]);
	printf ("  |-----------------------------------------|\n"); 

	// printing the witnesses (12 & 13) and judge (14)
	printf ("  |             |             |             |\n");
	printf ("  |     %s     |     %s     |     %s     |\n"
		"  |     %s     |     %s     |     %s     |\n"
		"  |     %s     |     %s     |     %s     |\n"
		"  |     %s     |     %s     |     %s     |\n",
		figures[13][0],figures[14][0],figures[12][0],
		figures[13][1],figures[14][1],figures[12][1],
		figures[13][2],figures[14][2],figures[12][2],
		figures[13][3],figures[14][3],figures[12][3]);
	
	printf ("  \\_________________________________________/\n\n");

}

/*****************************************/
/*     Geomant : a basic implementation  */
/*  of the geomanteia intended as a first*/
/*  C training project                   */
/*  copyright © Sylvain Saboua    */
/*  <sylvain ! saboua (|) free ! fr>     */
/*****************************************/

# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <unistd.h>

// figures initialization (all 15 figures)
char *figures[15][4] = {
	// mothers
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},

	// daughters
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},

	// nieces
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},

	// witnesses & judge
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "},
	{"   ", "   ", "   ", "   "}
} ;

// used to temporarily store user input, which may be anything other than \0 and \n
char *txt_raw_scrap = NULL ;
size_t txt_raw_scrap_size = 0UL ;


/*

	"mantize" : input fuction

 This function gathers a string of user input
 and returns a 0 or 1 for the evenness or
 oddity of the number of characters. It is called
 in a sequence by the next function to generate
 the figures one by one.

*/

int mantize ( char *body_part, char *mother_figure_n ) {
	printf ( "Hold or repeatedly press a key or keys to generate the %s of the %s mother, then press Enter:\n",
		body_part, mother_figure_n ) ;
	getline ( &txt_raw_scrap, &txt_raw_scrap_size, stdin ) ; 
	return ( ( strlen ( txt_raw_scrap ) -1 ) % 2 ) ; // substracting 1 as the \n character
}


/*
 
	"generate" fuction:

 This function takes the cast result (being 0 or 1,
 odd or even) and use it to generate
 all 15 figures, from the mothers down to the
 daughters, nieces, witnesses and judge.

*/

int generate(){
	
	// arrays containing the values for the subsequent divination in the function called.
	static char *mother_figures_n[] = { "FIRST", "SECOND", "THIRD", "FOURTH" } ; int n_figure ;
	static char *body_parts[] = { "HEAD", "NECK", "BODY", "FEET" } ; int n_bodypart ;

	// generating the mothers by calling the mantize() function
	for ( n_figure = 0 ; n_figure < 4 ; n_figure++ ) {
		for ( n_bodypart = 0 ; n_bodypart < 4 ; n_bodypart++ ) {
			figures[n_figure][n_bodypart] =
			(0 == mantize(body_parts[n_bodypart], mother_figures_n[n_figure])) ? "* *" : " * " ;
			system("clear");
		}
	}
	
	//generating the four daughters from the four mothers

	figures[4][0] = figures[0][0] ;
	figures[4][1] = figures[1][0] ;
	figures[4][2] = figures[2][0] ;
	figures[4][3] = figures[3][0] ;
	
	figures[5][0] = figures[0][1] ;
	figures[5][1] = figures[1][1] ;
	figures[5][2] = figures[2][1] ;
	figures[5][3] = figures[3][1] ;
	
	figures[6][0] = figures[0][2] ;
	figures[6][1] = figures[1][2] ;
	figures[6][2] = figures[2][2] ;
	figures[6][3] = figures[3][2] ;
	
	figures[7][0] = figures[0][3] ;
	figures[7][1] = figures[1][3] ;
	figures[7][2] = figures[2][3] ;
	figures[7][3] = figures[3][3] ;
	
	// generating the nieces
	
	figures[8][0] = ( figures[0][0] == figures[1][0] ) ? "* *" : " * " ;
	figures[8][1] = ( figures[0][1] == figures[1][1] ) ? "* *" : " * " ;
	figures[8][2] = ( figures[0][2] == figures[1][2] ) ? "* *" : " * " ;
	figures[8][3] = ( figures[0][3] == figures[1][3] ) ? "* *" : " * " ;
	
	figures[9][0] = ( figures[2][0] == figures[3][0] ) ? "* *" : " * " ;
	figures[9][1] = ( figures[2][1] == figures[3][1] ) ? "* *" : " * " ;
	figures[9][2] = ( figures[2][2] == figures[3][2] ) ? "* *" : " * " ;
	figures[9][3] = ( figures[2][3] == figures[3][3] ) ? "* *" : " * " ;
	
	figures[10][0] = ( figures[4][0] == figures[5][0] ) ? "* *" : " * " ;
	figures[10][1] = ( figures[4][1] == figures[5][1] ) ? "* *" : " * " ;
	figures[10][2] = ( figures[4][2] == figures[5][2] ) ? "* *" : " * " ;
	figures[10][3] = ( figures[4][3] == figures[5][3] ) ? "* *" : " * " ;
	
	figures[11][0] = ( figures[6][0] == figures[7][0] ) ? "* *" : " * " ;
	figures[11][1] = ( figures[6][1] == figures[7][1] ) ? "* *" : " * " ;
	figures[11][2] = ( figures[6][2] == figures[7][2] ) ? "* *" : " * " ;
	figures[11][3] = ( figures[6][3] == figures[7][3] ) ? "* *" : " * " ;
	
	// generating the witnesses
	
	figures[12][0] = ( figures[8][0] == figures[9][0] ) ? "* *" : " * " ;
	figures[12][1] = ( figures[8][1] == figures[9][1] ) ? "* *" : " * " ;
	figures[12][2] = ( figures[8][2] == figures[9][2] ) ? "* *" : " * " ;
	figures[12][3] = ( figures[8][3] == figures[9][3] ) ? "* *" : " * " ;
	
	figures[13][0] = ( figures[10][0] == figures[11][0] ) ? "* *" : " * " ;
	figures[13][1] = ( figures[10][1] == figures[11][1] ) ? "* *" : " * " ;
	figures[13][2] = ( figures[10][2] == figures[11][2] ) ? "* *" : " * " ;
	figures[13][3] = ( figures[10][3] == figures[11][3] ) ? "* *" : " * " ;
	 
	//generating the judge

	figures[14][0] = ( figures[12][0] == figures[13][0] ) ? "* *" : " * " ;
	figures[14][1] = ( figures[12][1] == figures[13][1] ) ? "* *" : " * " ;
	figures[14][2] = ( figures[12][2] == figures[13][2] ) ? "* *" : " * " ;
	figures[14][3] = ( figures[12][3] == figures[13][3] ) ? "* *" : " * " ;
	
	return *figures[14][3] ;
}


/*

	main / "display" function:

 This function will display onscreen the final
 geomantic Shield for the given divination.
 The "-" & "|" characters are used for separation
 while the dots are displayed using "*"

*/

int main(){
	
	// the user is asked the object of the divination
	char *txt_topic ; size_t txt_topic_size = 0UL ;
	printf("What is the subject title of your enquiry ?\n");
	getline ( &txt_topic, &txt_topic_size, stdin ) ; 

	generate(); // calling upon the previous function. this line is the core of the program
	
	printf ("\n    %s\n", txt_topic);
	printf ("  |-----------------------------------------|\n"); // top line
	
	// printing the first 8 figures (4 daughters & 4 mothers)
	printf ("  | %s  %s  %s  %s | %s  %s  %s  %s |\n"
		"  | %s  %s  %s  %s | %s  %s  %s  %s |\n"
		"  | %s  %s  %s  %s | %s  %s  %s  %s |\n"
		"  | %s  %s  %s  %s | %s  %s  %s  %s |\n",
		figures[7][0],figures[6][0],figures[5][0],figures[4][0],
		figures[3][0],figures[2][0],figures[1][0],figures[0][0],
		figures[7][1],figures[6][1],figures[5][1],figures[4][1],
		figures[3][1],figures[2][1],figures[1][1],figures[0][1],
		figures[7][2],figures[6][2],figures[5][2],figures[4][2],
		figures[3][2],figures[2][2],figures[1][2],figures[0][2],
		figures[7][3],figures[6][3],figures[5][3],figures[4][3],
		figures[3][3],figures[2][3],figures[1][3],figures[0][3]);
	printf ("  |-----------------------------------------|\n"); 
	
	// printing the four nieces
	printf ("  |    %s      %s    |    %s      %s    |\n"
		"  |    %s      %s    |    %s      %s    |\n"
		"  |    %s      %s    |    %s      %s    |\n"
		"  |    %s      %s    |    %s      %s    |\n",
		figures[11][0],figures[10][0],figures[9][0],figures[8][0],
		figures[11][1],figures[10][1],figures[9][1],figures[8][1],
		figures[11][2],figures[10][2],figures[9][2],figures[8][2],
		figures[11][3],figures[10][3],figures[9][3],figures[8][3]);
	printf ("  |-----------------------------------------|\n"); 

	// printing the witnesses (12 & 13) and judge (14)
	printf ("  |             |             |             |\n");
	printf ("  |     %s     |     %s     |     %s     |\n"
		"  |     %s     |     %s     |     %s     |\n"
		"  |     %s     |     %s     |     %s     |\n"
		"  |     %s     |     %s     |     %s     |\n",
		figures[13][0],figures[14][0],figures[12][0],
		figures[13][1],figures[14][1],figures[12][1],
		figures[13][2],figures[14][2],figures[12][2],
		figures[13][3],figures[14][3],figures[12][3]);
	
	printf ("  \\_________________________________________/\n\n");

}

Reply via email to