src/util/* include/base.h makes available util_concat(), util_read_file()

introduces the enum axis { X_AXIS, Y_AXIS, Z_AXIS }

The use of util_concat() modifies the memory indirect leaks (not direct).
==23744== LEAK SUMMARY:
==23744==    definitely lost: 5,008 bytes in 54 blocks
==23744==    indirectly lost: 16,151 bytes in 673 blocks

Doc minor modifications (use __function_name__ instead of "function name").
This commit is contained in:
Jean Sirmai 2024-11-21 11:54:13 +01:00
parent f3564d0462
commit 1bcb74e3cb
Signed by: jean
GPG Key ID: FB3115C340E057E3
12 changed files with 312 additions and 74 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -1,25 +1,27 @@
/* /**
* Gem-graph OpenGL experiments * @file
* base header
* *
* Desc: Base header * This file is part of Gem-graph.
* *
* Copyright (C) 2023 Arthur Menges <arthur.menges@a-lec.org> * @cond LICENSE
* Copyright (C) 2023 Adrien Bourmault <neox@a-lec.org> * Copyright © 2021 Libre en Communs <contact@a-lec.org>
* Copyright © 2021-2024 Adrien Bourmault <neox@a-lec.org>
* Copyright © 2021-2024 Jean Sirmai <jean@a-lec.org>
* *
* This file is part of Gem-graph. * This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
* *
* This program is free software: you can redistribute it and/or modify * This program is distributed in the hope that it will be useful, but WITHOUT
* it under the terms of the GNU Affero General Public License as published by * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* the Free Software Foundation, either version 3 of the License, or * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* (at your option) any later version. * details.
* *
* This program is distributed in the hope that it will be useful, * You should have received a copy of the GNU Affero General Public License
* but WITHOUT ANY WARRANTY; without even the implied warranty of * along with this program. If not, see <http://www.gnu.org/licenses/>.
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * @endcond
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
@ -35,33 +37,39 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <glib-2.0/glib.h> #include <glib-2.0/glib.h>
//#define G_APPLICATION_DEFAULT_FLAGS 0 //#define G_APPLICATION_DEFAULT_FLAGS 0
enum { X_AXIS, Y_AXIS, Z_AXIS, N_AXIS }; // < used by : graph_area.h struct arrow_t { uint load; uint site; uint x; uint y; uint z; };
enum { HOME_MODE, RUN_MODE, EDIT_MODE, PRESENTATION_MODE, N_MODE }; // Gem-graph modes static inline char *read_file(char *filename);
struct arrow_t { uint load; uint site; uint x; uint y; uint z; }; // describes an arrow
static inline char *read_file(char *filename); // < used by : init.c
/* I'm standing on Earth (or any spinning spheroid) and looking towards its North pole, then : /**
X - X = EAST - WEST = rouge - cyan * I'm standing on Earth (or any spinning spheroid)
Y - Y = ZENITH - NADIR = vert - magenta (fuschia) * and looking towards its North pole,
Z - Z = NORTH - SOUTH = bleu - jaune */
#define EAST 0 // + x rouge
#define WEST 1 // - x cyan
#define ZENITH 2 // + y vert
#define NADIR 3 // - y magenta
#define SOUTH 4 // + z bleu
#define NORTH 5 // - z jaune
/*
* char *read_file(char *filename) reads a file from filename into a provided buffer
* *
* @param filename, file name * then :
* contents, target ptr
* *
* @return void * X - X = EAST - WEST = red - cyan
* Y - Y = ZENITH - NADIR = green - magenta (fuschia)
* Z - Z = SOUTH - NORTH = blue - yellow
*/
enum axis { X_AXIS, Y_AXIS, Z_AXIS, N_AXIS };
#define EAST 0 /**< +x red */
#define WEST 1 /**< -x cyan */
#define ZENITH 2 /**< +y green */
#define NADIR 3 /**< -y magenta or fuschia */
#define SOUTH 4 /**< +z blue */
#define NORTH 5 /**< -z yellow */
/**
* char *read_file(char *filename)
*
* reads a file from filename into a provided buffer
*
* @param *filename
*/ */
static inline char *read_file(char *filename) static inline char *read_file(char *filename)
{ {

View File

@ -219,8 +219,8 @@ void fsm_clear_log (struct fsm_log_t *);
void fsm_clear_log_unit (struct fsm_log_unit_t *); void fsm_clear_log_unit (struct fsm_log_unit_t *);
void fsm_add_log_event (struct fsm_log_t *gg_logs, void fsm_add_log_event (struct fsm_log_t *gg_logs,
char *file_source, const char *file_source,
char *function_source, const char *function_source,
char *string_value); char *string_value);
int fsm_get_log_length(struct fsm_log_t *); int fsm_get_log_length(struct fsm_log_t *);
@ -236,12 +236,12 @@ long fsm_remove_log (struct fsm_log_t *gg_logs,
void fsm_add_log (int severity, void fsm_add_log (int severity,
int source, int source,
char *file_source, const char *file_source,
char *function_source, const char *function_source,
char *string_value); char *string_value);
void fsm_relay_init_log(); void fsm_relay_init_log();
void fsm_relay_close_log(); void fsm_relay_close_log();
void fsm_init (char *initial_message_from_main); void fsm_init();
void fsm_close (char *final_message_from_main); void fsm_close();

37
include/util.h Normal file
View File

@ -0,0 +1,37 @@
/**
* @file
* utilities header
*
* This file is part of Gem-graph.
*
* @cond LICENSE
* Copyright © 2021 Libre en Communs <contact@a-lec.org>
* Copyright © 2021-2024 Adrien Bourmault <neox@a-lec.org>
* Copyright © 2021-2024 Jean Sirmai <jean@a-lec.org>
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* @endcond
*/
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <gtk-4.0/gtk/gtk.h>
#include "../include/fsm.h"
char *util_read_file (char *filename);
char *util_concat (const char *str, ...);

View File

@ -140,16 +140,16 @@ static void fsm_structures_close()
* *
* @param *initial_info_from_main * @param *initial_info_from_main
*/ */
void fsm_init (char *initial_info_from_main) void fsm_init()
{ {
fsm_relay_init_log(); fsm_relay_init_log();
fsm_add_log (INFO, MAIN, "main", initial_info_from_main, fsm_add_log (INFO, MAIN, "fsm/control", __func__,
"👋️ (☕️) Hi everybody ! Here is Gem-Graph."); "👋️ (☕️) Hi everybody ! Here is Gem-Graph.");
fsm_add_log (INFO, FSM, "fsm/control", "fsm initialisation", "has began ✍️"); fsm_add_log (INFO, FSM, "fsm/control", __func__, "has began ✍️");
fsm_structures_init(); fsm_structures_init();
fsm_add_log (INFO, FSM, "fsm/control", "fsm initialisation", "has ended 😇️"); fsm_add_log (INFO, FSM, "fsm/control", __func__, "has ended 😇️");
} }
/** /**
@ -181,16 +181,17 @@ void fsm_init (char *initial_info_from_main)
* *
* @param *closing_info_from_main * @param *closing_info_from_main
*/ */
void fsm_close (char *closing_info_from_main) void fsm_close()
{ {
fsm_add_log (INFO, FSM, "fsm/control", "fsm closing", "has began"); fsm_add_log (INFO, FSM, "fsm/control", __func__, "has began");
fsm_structures_close(); fsm_structures_close();
fsm_add_log (INFO, FSM, "fsm/control", "fsm closing", "has ended"); fsm_add_log (INFO, FSM, "fsm/control", __func__, "has ended");
fsm_add_log (INFO, MAIN, "main", closing_info_from_main, fsm_add_log (INFO, MAIN, "fsm/control", __func__,
"👋️😄️ That'all folks !"); "👋️😄️ That'all folks !");
fsm_relay_close_log(); /**< fsm_clear_log(() can't be called from here fsm_relay_close_log(); /**< fsm_clear_log(() can't be called from here
* because static fsm_log_struct gg_logs * because static fsm_log_struct gg_logs
* is in src/fsm/log/manager.c */ * is in src/fsm/log/manager.c */
} }

View File

@ -94,8 +94,8 @@ static struct fsm_log_t gg_logs = { 0 };
*/ */
void fsm_add_log (int severity, void fsm_add_log (int severity,
int source, int source,
char *file_source, const char *file_source,
char *function_source, const char *function_source,
char *string_value) char *string_value)
{ {
if if

View File

@ -116,8 +116,8 @@ void fsm_clear_log_unit (struct fsm_log_unit_t *unit)
* @param *string_value * @param *string_value
*/ */
void fsm_add_log_event (struct fsm_log_t *gg_logs, void fsm_add_log_event (struct fsm_log_t *gg_logs,
char *file_source, const char *file_source,
char *function_source, const char *function_source,
char *string_value) char *string_value)
{ {
struct timeval tv; struct timeval tv;

View File

@ -63,15 +63,15 @@ int main (int argc, char **argv)
GtkApplication *app; GtkApplication *app;
int status; int status;
fsm_init ("first instruction / first log"); fsm_init();
fsm_add_log (INFO, MAIN, "main", fsm_add_log (INFO, MAIN, __func__,
"*app = gtk_application_new()", "*app = gtk_application_new()",
"| 👉️ trigger app initialization"); "| 👉️ trigger app initialization");
app = gtk_application_new ("org.gem-graph", G_APPLICATION_DEFAULT_FLAGS); app = gtk_application_new ("org.gem-graph", G_APPLICATION_DEFAULT_FLAGS);
fsm_add_log (INFO, MAIN, "main", fsm_add_log (INFO, MAIN, __func__,
"g signal connect (activate)", "g signal connect (activate)",
"| 👉️ windows creation requested"); "| 👉️ windows creation requested");
@ -80,9 +80,9 @@ int main (int argc, char **argv)
status = g_application_run (G_APPLICATION (app), argc, argv); status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app); g_object_unref (app);
fsm_add_log (INFO, MAIN, "main", "g_object unref (app)", "| 👌️ bye bye app !"); fsm_add_log (INFO, MAIN, __func__, "g_object unref (app)", "| 👌️ bye bye app !");
fsm_close("last instruction / last log"); fsm_close();
return status; return status;
} }

64
src/util/io.c Normal file
View File

@ -0,0 +1,64 @@
/**
* @file
* input output
*
* This file is part of Gem-graph.
*
* @cond LICENSE
* Copyright © 2021 Libre en Communs <contact@a-lec.org>
* Copyright © 2021-2024 Adrien Bourmault <neox@a-lec.org>
* Copyright © 2021-2024 Jean Sirmai <jean@a-lec.org>
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* @endcond
*/
#include "../../include/util.h"
#include "../../include/base.h"
/**
* reads a file from filename into a provided buffer
*
* @param *filename
*
* @returns char
*/
char *util_read_file(char *filename)
{
int fd;
int filesize;
char *contents;
fd = open(filename, O_RDONLY);
if (fd < 0) {
printf("Couldn't read file: %s\n",filename);
return NULL;
}
filesize = lseek(fd, 0, SEEK_END) + 1 ;
contents = g_malloc(filesize * sizeof(char));
assert (contents);
lseek(fd, 0, SEEK_SET);
read(fd,contents,filesize);
contents[filesize-1] = '\0';
close(fd);
return contents;
}

131
src/util/strings.c Normal file
View File

@ -0,0 +1,131 @@
/**
* @file
* concat
*
* @cond LICENSE
* This file is part of Gem-graph.
*
* Copyright © 2021 Libre en Communs <contact@a-lec.org>
* Copyright © 2021-2024 Adrien Bourmault <neox@a-lec.org>
* Copyright © 2021-2024 Jean Sirmai <jean@a-lec.org>
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* @endcond
*/
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
/**
* Programmers using the strcat function can easily be recognized as lazy and
* reckless 🤨 (quoted from: The GNU C Library (glibc) manual - 5.5
* Concatenating Strings).
*
* Whenever a programmer feels the need to use strcat she or he should think twice
* and look through the program to see whether the code cannot be rewritten
* to take advantage of already calculated results.
* The related functions strlcat, strncat, wcscat and wcsncat are almost always unnecessary, too.
* Again: it is almost always unnecessary to use functions like strcat. 😄
*
* Before calling vprintf or the other functions listed in this section,
* you must call va_start (see Variadic Functions) to initialize a pointer to the variable arguments.
* Then you can call va_arg to fetch the arguments that you want to handle yourself.
* This advances the pointer past those arguments.
*
* Once your va_list pointer is pointing at the argument of your choice, you are ready to call vprintf.
* That argument and all subsequent arguments that were passed to your function
* are used by vprintf along with the template that you specified separately.
*
* ---
*
* A.2 Variadic Functions
*
* ISO C defines a syntax for declaring a function to take a variable number or type of arguments.
* (Such functions are referred to as varargs functions or variadic functions.)
* However, the language itself provides no mechanism for such functions to access
* their non-required arguments; instead, you use the variable arguments macros defined in stdarg.h.
*
* This section describes how to declare variadic functions, how to write them,
* and how to call them properly.
*
* https://sourceware.org/glibc/manual/latest/html_mono/libc.html#Variadic-Prototypes
*
* see (in glibc/manual) > ellipsis () A.2.2.2 Receiving the Argument Values
*
* ---
*
* NB 'at ref' desactivated TODO
*
* @callergraph
* @see on_app_activation()
*
* @param *str
* @param ...
*
* @return *
*/
char *
util_concat (const char *str, ...)
{
size_t allocated = 100;
char *result = malloc (allocated);
if (result != NULL)
{
va_list ap;
size_t resultlen = 0;
char *newp;
va_start (ap, str);
for (const char *s = str; s != NULL; s = va_arg (ap, const char *))
{
size_t len = strlen (s);
/* Resize the allocated memory if necessary. */
if (resultlen + len + 1 > allocated)
{
allocated += len;
newp = reallocarray (result, allocated, 2);
allocated *= 2;
if (newp == NULL)
{
free (result);
return NULL;
}
result = newp;
}
memcpy (result + resultlen, s, len);
resultlen += len;
}
/* Terminate the result string. */
result[resultlen++] = '\0';
/* Resize memory to the optimal size. */
newp = realloc (result, resultlen);
if (newp != NULL)
result = newp;
va_end (ap);
}
return result;
}

View File

@ -42,7 +42,7 @@
void widget_design_main_window (GtkWindow *main_window, GtkApplication *app) void widget_design_main_window (GtkWindow *main_window, GtkApplication *app)
{ {
fsm_add_log (INFO, TOPBAR, "widget/main_window/design", fsm_add_log (INFO, TOPBAR, "widget/main_window/design",
"main window", "start of design"); __func__, "start of design");
/* GtkWidget *topbar = GTK_WIDGET (gtk_header_bar_new ()); */ /* GtkWidget *topbar = GTK_WIDGET (gtk_header_bar_new ()); */
@ -58,5 +58,5 @@ void widget_design_main_window (GtkWindow *main_window, GtkApplication *app)
// g_object_unref (e_coli); // g_object_unref (e_coli);
fsm_add_log (INFO, TOPBAR, "widget/main_window/design", fsm_add_log (INFO, TOPBAR, "widget/main_window/design",
"main window", "ready for presentation"); __func__, "end of design -> present");
} }

View File

@ -32,6 +32,7 @@
#include "../../include/widget.h" #include "../../include/widget.h"
#include "../../include/fsm.h" #include "../../include/fsm.h"
#include "../../include/util.h"
#include <stdio.h> #include <stdio.h>
@ -57,7 +58,7 @@ static GtkWindow *window;
*/ */
void on_app_activation (GtkApplication *app) void on_app_activation (GtkApplication *app)
{ {
fsm_add_log (INFO, WIDGETS, "widget/manager", "app activation()", "has began"); fsm_add_log (INFO, WIDGETS, "widget/manager", __func__, "has began");
// on_windows_activation() is in: widget/manager NOT in: src/signal // on_windows_activation() is in: widget/manager NOT in: src/signal
// g_application_activate (G_APPLICATION (app)); < how ? > in main is // g_application_activate (G_APPLICATION (app)); < how ? > in main is
@ -82,13 +83,9 @@ void on_app_activation (GtkApplication *app)
g_signal_connect(window, "close-request", G_CALLBACK (on_window_close_request), (void *)(long long)window_int_id); g_signal_connect(window, "close-request", G_CALLBACK (on_window_close_request), (void *)(long long)window_int_id);
//printf ("gtk_application_window_id = %s = %d\n", window_char_id, window_int_id); char *temp = util_concat ("window_get_id = ", window_char_id, NULL);
fsm_add_log (INFO, WIDGETS, "widget/manager", __func__, temp);
fsm_add_log (INFO, WIDGETS, "widget/manager", "gtk_application_window_get_id", free(temp);
window_char_id);//"sprintf(window_id,...) << fails. Why ?");
//printf ("gtk_application_window_get_id (main_window) = %d\n",
//gtk_application_window_get_id (GTK_APPLICATION_WINDOW (main_window)));
widget_design_main_window (window, app); widget_design_main_window (window, app);
@ -117,14 +114,14 @@ void on_app_activation (GtkApplication *app)
g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_b)); g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_b));
g_signal_connect (act_b, "activate", G_CALLBACK (action_b), app2);*/ g_signal_connect (act_b, "activate", G_CALLBACK (action_b), app2);*/
fsm_add_log (INFO, WIDGETS, "widget/manager", "app activation()", fsm_add_log (INFO, WIDGETS, "widget/manager", __func__,
"has ended 🧐️ | 👉️ a new session starts"); "has ended 🧐️ | 👉️ a new session starts");
} }
gboolean on_window_close_request (GtkWindow *window, gpointer user_data) gboolean on_window_close_request (GtkWindow *window, gpointer user_data)
{ {
fsm_add_log (INFO, WIDGETS, "widget/manager", "window close request()", fsm_add_log (INFO, WIDGETS, "widget/manager", __func__,
"freeing all ressources !"); "freeing all ressources !");
// free the only child // free the only child