From 293d4f86fb4a4a843a252187dc86ac7e62a00cab Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 26 Mar 2024 09:45:37 +0100 Subject: [PATCH 01/18] branch commit test --- GITHELP.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/GITHELP.md b/GITHELP.md index ce74b66..cee0168 100644 --- a/GITHELP.md +++ b/GITHELP.md @@ -1,5 +1,11 @@ # GIT Help +Marker : develop branch + +## Strategie + + + ## First steps git init From 87aaecf6bbf765ca606d6ab7544f5c77467a7bca Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 26 Mar 2024 16:18:12 +0100 Subject: [PATCH 02/18] wip keyboad --- GITHELP.md | 2 +- main.c | 25 ++++++++++--------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/GITHELP.md b/GITHELP.md index cee0168..637868c 100644 --- a/GITHELP.md +++ b/GITHELP.md @@ -1,6 +1,6 @@ # GIT Help -Marker : develop branch +Marker : feature-keybord branch ## Strategie diff --git a/main.c b/main.c index 5c57300..b9ebd48 100644 --- a/main.c +++ b/main.c @@ -1,12 +1,16 @@ #include +#define BUTTON_NUM 20 + GtkWidget *window; GtkWidget *entry; GtkWidget *button; GtkWidget *grid; -GtkWidget *buttons[10]; +GtkWidget *buttons[BUTTON_NUM]; GtkWidget *box; +const char *buttonlabels[BUTTON_NUM] = {"C","/","*","-","7","8","9","+","4","5","6","(","1","2","3",")"," ","0",",","="}; + // Funktion zum Behandeln des Button-Klicks void button_clicked(GtkWidget *button, gpointer data) { const char *text = gtk_entry_get_text(GTK_ENTRY(data)); @@ -40,34 +44,25 @@ int main(int argc, char *argv[]) { // Verbinden Sie den delete-event-Handler mit gtk_main_quit() g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL); -/**/ - // Erstellen Sie ein GtkGrid-Widget für den Tastenblock grid = gtk_grid_new(); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); gtk_grid_set_row_spacing(GTK_GRID(grid), 5); // Erstellen Sie 10 Buttons für die Ziffern 0-9 - for (int i = 0; i < 10; i++) { - buttons[i] = gtk_button_new_with_label(g_strdup_printf("%d", i)); + for (int i = 0; i < BUTTON_NUM; i++) { + buttons[i] = gtk_button_new_with_label(buttonlabels[i]); g_signal_connect(buttons[i], "clicked", G_CALLBACK(number_button_clicked), entry); } // Fügen Sie die Buttons in das Grid-Widget ein int row = 0, column = 0; - for (int i = 0; i < 10; i++) { - gtk_grid_attach(GTK_GRID(grid), buttons[i], column, row, 1, 1); - if (column == 2) { - column = 0; - row++; - } else { - column++; - } + for (int i = 0; i < BUTTON_NUM; i++) { + gtk_grid_attach(GTK_GRID(grid), buttons[i], i % 4, i / 4, 1, 1); } -/**/ // Erstellen Sie einen Box-Container und fügen Sie das Eingabefeld, den Button und den Tastenblock hinzu - box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), grid, TRUE, TRUE, 0); From bc52f5e096877629f52f4c10bf9024758bc1b50f Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 26 Mar 2024 16:19:35 +0100 Subject: [PATCH 03/18] wip again keyboard --- GITHELP.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GITHELP.md b/GITHELP.md index 637868c..114ba87 100644 --- a/GITHELP.md +++ b/GITHELP.md @@ -2,6 +2,8 @@ Marker : feature-keybord branch +Noch eine Änderung + ## Strategie From 99c933fea753308326fbb346cf05f323c920df99 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 27 Mar 2024 08:11:50 +0100 Subject: [PATCH 04/18] cleanup and first button logic --- main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index b9ebd48..1b49889 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,5 @@ #include +// https://developer-old.gnome.org/gtk3/stable/GtkWidget.html #define BUTTON_NUM 20 @@ -19,9 +20,16 @@ void button_clicked(GtkWidget *button, gpointer data) { // Funktion zum Behandeln der Ziffern-Buttons void number_button_clicked(GtkWidget *button, gpointer data) { - const char *number = gtk_button_get_label(GTK_BUTTON(button)); - gtk_entry_set_text(GTK_ENTRY(data), number); -// gtk_entry_append_text(GTK_ENTRY(data), number); + const char *label = gtk_button_get_label(GTK_BUTTON(button)); + char button_char = *label; + switch (button_char) { + case 'C': + gtk_entry_set_text (GTK_ENTRY(data), ""); + break; + default: + GtkEntryBuffer *buffer = gtk_entry_get_buffer (GTK_ENTRY(data)); + gtk_entry_buffer_insert_text (buffer, -1, label, -1); + } } int main(int argc, char *argv[]) { @@ -56,7 +64,6 @@ int main(int argc, char *argv[]) { } // Fügen Sie die Buttons in das Grid-Widget ein - int row = 0, column = 0; for (int i = 0; i < BUTTON_NUM; i++) { gtk_grid_attach(GTK_GRID(grid), buttons[i], i % 4, i / 4, 1, 1); } From 7d769f623e5d9bad40ca2ea7199c008025416423 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 27 Mar 2024 08:13:19 +0100 Subject: [PATCH 05/18] make reworked --- makefile | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/makefile b/makefile index d9d1c9d..94ff93e 100644 --- a/makefile +++ b/makefile @@ -18,21 +18,13 @@ LIBS = \ OBJS = $(SRCS:.c=.o) # Flagge für GTK+-Entwicklung -GTK3_CFLAGS = -Wall `pkg-config --cflags glib-2.0` \ - -I/usr/include/gtk-3.0 \ - -I/usr/include/glib-2.0 \ - -I/usr/include/pango-1.0 \ - -I/usr/include/harfbuzz \ - -I/usr/include/cairo \ - -I/usr/include/gdk-pixbuf-2.0 \ - -I/usr/include/atk-1.0 +GTK3_CFLAGS = -Wall `pkg-config --cflags gtk+-3.0` # Flagge für C-Compiler CFLAGS = $(GTK3_CFLAGS) # Flagge für Linker LDFLAGS = `pkg-config --libs gtk+-3.0` -L/usr/local/lib -L/usr/lib -#LDFLAGS = `pkg-config --libs glib-2.0` -L/usr/local/lib -L/usr/lib # Programmname PROGRAM = $(PROJECT) From 80369225a8409e804f9859c75282f40f84803b5a Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 27 Mar 2024 10:21:36 +0100 Subject: [PATCH 06/18] edit comment --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 1b49889..884e5a3 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ #include -// https://developer-old.gnome.org/gtk3/stable/GtkWidget.html +// https://developer-old.gnome.org/gtk3/stable #define BUTTON_NUM 20 From 69f1c4579d91b61350672e241fecda42e1d98307 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 27 Mar 2024 11:45:03 +0100 Subject: [PATCH 07/18] gui work --- main.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/main.c b/main.c index 884e5a3..2fa62c9 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,5 @@ #include +// https://docs.gtk.org/gtk3/ // https://developer-old.gnome.org/gtk3/stable #define BUTTON_NUM 20 @@ -35,52 +36,55 @@ void number_button_clicked(GtkWidget *button, gpointer data) { int main(int argc, char *argv[]) { gtk_init(&argc, &argv); - // Erstellen Sie ein Fenster + // Erstellt ein Fenster window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Hello World"); - gtk_window_set_default_size(GTK_WINDOW(window), 300, 100); + gtk_window_set_default_size(GTK_WINDOW(window), 320, 100); - // Erstellen Sie ein Eingabefeld + // Erstellt ein Eingabefeld entry = gtk_entry_new(); - // Erstellen Sie einen Button + // Erstellt einen Button button = gtk_button_new_with_label("Eingabe ausgeben"); - - // Verbinden Sie den Button-Klick mit der Funktion button_clicked + + // Verbindt den Button-Klick mit der Funktion button_clicked g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), entry); - // Verbinden Sie den delete-event-Handler mit gtk_main_quit() + // Verbindt den delete-event-Handler mit gtk_main_quit() g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL); - // Erstellen Sie ein GtkGrid-Widget für den Tastenblock + // Erstellt ein GtkGrid-Widget für den Tastenblock grid = gtk_grid_new(); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); gtk_grid_set_row_spacing(GTK_GRID(grid), 5); - // Erstellen Sie 10 Buttons für die Ziffern 0-9 for (int i = 0; i < BUTTON_NUM; i++) { + // Erstellen der Buttons buttons[i] = gtk_button_new_with_label(buttonlabels[i]); g_signal_connect(buttons[i], "clicked", G_CALLBACK(number_button_clicked), entry); - } - // Fügen Sie die Buttons in das Grid-Widget ein - for (int i = 0; i < BUTTON_NUM; i++) { + // Fügt die Buttons in das Grid-Widget ein gtk_grid_attach(GTK_GRID(grid), buttons[i], i % 4, i / 4, 1, 1); } - // Erstellen Sie einen Box-Container und fügen Sie das Eingabefeld, den Button und den Tastenblock hinzu - box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(box), grid, TRUE, TRUE, 0); + // Erstellt einen Box-Container und fügt das Eingabefeld, den Button und den Tastenblock hinzu + box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2); + gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 5); + gtk_widget_set_margin_start(entry, 10); + gtk_widget_set_margin_end(entry, 10); + + gtk_box_pack_start(GTK_BOX(box), grid, TRUE, TRUE, 5); + gtk_widget_set_halign(grid, GTK_ALIGN_CENTER); + + gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 5); - // Fügen Sie den Box-Container zum Fenster hinzu + // Fügt den Box-Container zum Fenster hinzu gtk_container_add(GTK_CONTAINER(window), box); - // Zeigen Sie alle Widgets an + // Zeigt alle Widgets an gtk_widget_show_all(window); - // Starten Sie die GTK+-Hauptschleife + // Startet die GTK+-Hauptschleife gtk_main(); return 0; From e1acb5b06d74680445dc651e04186024614e5902 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 27 Mar 2024 13:33:11 +0100 Subject: [PATCH 08/18] first gtk4 --- CHANGELOG.md | 6 ++++-- main.c | 51 +++++++++++++++++++++++++++++---------------------- makefile | 6 +++--- settings.json | 2 +- 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f052f1..5f8b3eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,5 +3,7 @@ GIT Testprojekt ## Change log -Version Branch Änderung -0.0.2 main Gtk Grundgerüst +Version Branch Änderung +0.0.2 main Gtk Grundgerüst +0.0.4 feature-gtk4 Umstellung auf gtk4 +'apt install libgtk-4-1 libgtk-4-dev libgtk-4-bin libgtk-4-common' diff --git a/main.c b/main.c index 884e5a3..079d319 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ #include -// https://developer-old.gnome.org/gtk3/stable +// https://docs.gtk.org/gtk4/ #define BUTTON_NUM 20 @@ -13,18 +13,21 @@ GtkWidget *box; const char *buttonlabels[BUTTON_NUM] = {"C","/","*","-","7","8","9","+","4","5","6","(","1","2","3",")"," ","0",",","="}; // Funktion zum Behandeln des Button-Klicks -void button_clicked(GtkWidget *button, gpointer data) { - const char *text = gtk_entry_get_text(GTK_ENTRY(data)); +void button_clicked(GtkWidget *button, gpointer data) +{ + const char *text = gtk_editable_get_text(GTK_EDITABLE(data)); printf("Der eingegebene Text ist: %s\n", text); } // Funktion zum Behandeln der Ziffern-Buttons -void number_button_clicked(GtkWidget *button, gpointer data) { +void number_button_clicked(GtkWidget *button, gpointer data) +{ const char *label = gtk_button_get_label(GTK_BUTTON(button)); char button_char = *label; switch (button_char) { case 'C': - gtk_entry_set_text (GTK_ENTRY(data), ""); +// gtk_entry_set_text (GTK_ENTRY(data), ""); + gtk_editable_set_text(GTK_EDITABLE(data), ""); break; default: GtkEntryBuffer *buffer = gtk_entry_get_buffer (GTK_ENTRY(data)); @@ -32,11 +35,10 @@ void number_button_clicked(GtkWidget *button, gpointer data) { } } -int main(int argc, char *argv[]) { - gtk_init(&argc, &argv); - +static void activate (GtkApplication *app, gpointer user_data) +{ // Erstellen Sie ein Fenster - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + window = gtk_application_window_new (app); gtk_window_set_title(GTK_WINDOW(window), "Hello World"); gtk_window_set_default_size(GTK_WINDOW(window), 300, 100); @@ -49,9 +51,6 @@ int main(int argc, char *argv[]) { // Verbinden Sie den Button-Klick mit der Funktion button_clicked g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), entry); - // Verbinden Sie den delete-event-Handler mit gtk_main_quit() - g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL); - // Erstellen Sie ein GtkGrid-Widget für den Tastenblock grid = gtk_grid_new(); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); @@ -70,18 +69,26 @@ int main(int argc, char *argv[]) { // Erstellen Sie einen Box-Container und fügen Sie das Eingabefeld, den Button und den Tastenblock hinzu box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(box), grid, TRUE, TRUE, 0); + gtk_box_append(GTK_BOX(box), entry); + gtk_box_append(GTK_BOX(box), button); + gtk_box_append(GTK_BOX(box), grid); // Fügen Sie den Box-Container zum Fenster hinzu - gtk_container_add(GTK_CONTAINER(window), box); + gtk_window_set_child (GTK_WINDOW (window), box); + + gtk_window_present (GTK_WINDOW (window)); +} - // Zeigen Sie alle Widgets an - gtk_widget_show_all(window); - // Starten Sie die GTK+-Hauptschleife - gtk_main(); +int main (int argc, char **argv) +{ + GtkApplication *app; + int status; - return 0; -} + app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE); + g_signal_connect(app, "activate", G_CALLBACK (activate), NULL); + status = g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + + return status; +} \ No newline at end of file diff --git a/makefile b/makefile index 94ff93e..0f75365 100644 --- a/makefile +++ b/makefile @@ -12,19 +12,19 @@ HDRS = \ # Bibliotheken LIBS = \ - -lgtk3 + -lgtk4 # Objektdateien OBJS = $(SRCS:.c=.o) # Flagge für GTK+-Entwicklung -GTK3_CFLAGS = -Wall `pkg-config --cflags gtk+-3.0` +GTK3_CFLAGS = -Wall `pkg-config --cflags gtk4` # Flagge für C-Compiler CFLAGS = $(GTK3_CFLAGS) # Flagge für Linker -LDFLAGS = `pkg-config --libs gtk+-3.0` -L/usr/local/lib -L/usr/lib +LDFLAGS = `pkg-config --libs gtk4` -L/usr/local/lib -L/usr/lib # Programmname PROGRAM = $(PROJECT) diff --git a/settings.json b/settings.json index c401ec2..6f4ac5a 100644 --- a/settings.json +++ b/settings.json @@ -1,5 +1,5 @@ { "c_cpp.includePath": [ - "/usr/include/gtk-3.0" // Ersetzen Sie diesen Pfad nach Bedarf + "/usr/include/gtk-4.0" // Ersetzen Sie diesen Pfad nach Bedarf ] } \ No newline at end of file From 502f9a921c1dc95bbe60a38c4016f323e1e0ee37 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 27 Mar 2024 14:13:16 +0100 Subject: [PATCH 09/18] gtk4 final --- main.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/main.c b/main.c index 079d319..5b35101 100644 --- a/main.c +++ b/main.c @@ -70,8 +70,19 @@ static void activate (GtkApplication *app, gpointer user_data) // Erstellen Sie einen Box-Container und fügen Sie das Eingabefeld, den Button und den Tastenblock hinzu box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_append(GTK_BOX(box), entry); - gtk_box_append(GTK_BOX(box), button); + gtk_widget_set_margin_top(entry, 10); + gtk_widget_set_margin_start(entry, 10); + gtk_widget_set_margin_end(entry, 10); + gtk_box_append(GTK_BOX(box), grid); + gtk_widget_set_halign(grid, GTK_ALIGN_CENTER); + gtk_widget_set_margin_top(grid, 10); + gtk_widget_set_margin_bottom(grid, 10); + + gtk_box_append(GTK_BOX(box), button); + gtk_widget_set_margin_start(button, 10); + gtk_widget_set_margin_end(button, 10); + gtk_widget_set_margin_bottom(button, 10); // Fügen Sie den Box-Container zum Fenster hinzu gtk_window_set_child (GTK_WINDOW (window), box); From d9bc1a207f46bc9b24e4ef357b76210f222a641b Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 27 Mar 2024 14:21:31 +0100 Subject: [PATCH 10/18] test --- main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/main.c b/main.c index f00d8c9..daa0a9e 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,6 @@ #include // https://docs.gtk.org/gtk4/ +// Test keyboard branch #define BUTTON_NUM 20 From dee2c5afae71e03040791e9cc9df2f7a2d99dd2f Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 27 Mar 2024 14:25:32 +0100 Subject: [PATCH 11/18] Gtk4 final --- main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main.c b/main.c index daa0a9e..c292f60 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,5 @@ #include // https://docs.gtk.org/gtk4/ -// Test keyboard branch #define BUTTON_NUM 20 @@ -40,7 +39,7 @@ static void activate (GtkApplication *app, gpointer user_data) { // Erstellen Sie ein Fenster window = gtk_application_window_new (app); - gtk_window_set_title(GTK_WINDOW(window), "Hello World"); + gtk_window_set_title(GTK_WINDOW(window), "Hello World Gtk4"); gtk_window_set_default_size(GTK_WINDOW(window), 320, 100); // Erstellt ein Eingabefeld From 4a1735e9bc4a6813f82ab5904b2344e5a93784e6 Mon Sep 17 00:00:00 2001 From: marsalien7 <164360817+marsalien7@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:47:21 +0100 Subject: [PATCH 12/18] change to Gtk4 (#2) * Gtk4 final --------- Co-authored-by: Martin --- CHANGELOG.md | 6 ++- GITHELP.md | 8 ++++ main.c | 116 +++++++++++++++++++++++++++++--------------------- makefile | 14 ++---- settings.json | 2 +- 5 files changed, 83 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f052f1..5f8b3eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,5 +3,7 @@ GIT Testprojekt ## Change log -Version Branch Änderung -0.0.2 main Gtk Grundgerüst +Version Branch Änderung +0.0.2 main Gtk Grundgerüst +0.0.4 feature-gtk4 Umstellung auf gtk4 +'apt install libgtk-4-1 libgtk-4-dev libgtk-4-bin libgtk-4-common' diff --git a/GITHELP.md b/GITHELP.md index ce74b66..114ba87 100644 --- a/GITHELP.md +++ b/GITHELP.md @@ -1,5 +1,13 @@ # GIT Help +Marker : feature-keybord branch + +Noch eine Änderung + +## Strategie + + + ## First steps git init diff --git a/main.c b/main.c index 5c57300..c292f60 100644 --- a/main.c +++ b/main.c @@ -1,85 +1,103 @@ #include +// https://docs.gtk.org/gtk4/ + +#define BUTTON_NUM 20 GtkWidget *window; GtkWidget *entry; GtkWidget *button; GtkWidget *grid; -GtkWidget *buttons[10]; +GtkWidget *buttons[BUTTON_NUM]; GtkWidget *box; +const char *buttonlabels[BUTTON_NUM] = {"C","/","*","-","7","8","9","+","4","5","6","(","1","2","3",")"," ","0",",","="}; + // Funktion zum Behandeln des Button-Klicks -void button_clicked(GtkWidget *button, gpointer data) { - const char *text = gtk_entry_get_text(GTK_ENTRY(data)); +void button_clicked(GtkWidget *button, gpointer data) +{ + const char *text = gtk_editable_get_text(GTK_EDITABLE(data)); printf("Der eingegebene Text ist: %s\n", text); } // Funktion zum Behandeln der Ziffern-Buttons -void number_button_clicked(GtkWidget *button, gpointer data) { - const char *number = gtk_button_get_label(GTK_BUTTON(button)); - gtk_entry_set_text(GTK_ENTRY(data), number); -// gtk_entry_append_text(GTK_ENTRY(data), number); +void number_button_clicked(GtkWidget *button, gpointer data) +{ + const char *label = gtk_button_get_label(GTK_BUTTON(button)); + char button_char = *label; + switch (button_char) { + case 'C': +// gtk_entry_set_text (GTK_ENTRY(data), ""); + gtk_editable_set_text(GTK_EDITABLE(data), ""); + break; + default: + GtkEntryBuffer *buffer = gtk_entry_get_buffer (GTK_ENTRY(data)); + gtk_entry_buffer_insert_text (buffer, -1, label, -1); + } } -int main(int argc, char *argv[]) { - gtk_init(&argc, &argv); - +static void activate (GtkApplication *app, gpointer user_data) +{ // Erstellen Sie ein Fenster - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(window), "Hello World"); - gtk_window_set_default_size(GTK_WINDOW(window), 300, 100); + window = gtk_application_window_new (app); + gtk_window_set_title(GTK_WINDOW(window), "Hello World Gtk4"); + gtk_window_set_default_size(GTK_WINDOW(window), 320, 100); - // Erstellen Sie ein Eingabefeld + // Erstellt ein Eingabefeld entry = gtk_entry_new(); - // Erstellen Sie einen Button + // Erstellt einen Button button = gtk_button_new_with_label("Eingabe ausgeben"); - - // Verbinden Sie den Button-Klick mit der Funktion button_clicked + + // Verbindt den Button-Klick mit der Funktion button_clicked g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), entry); - // Verbinden Sie den delete-event-Handler mit gtk_main_quit() - g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL); - -/**/ - - // Erstellen Sie ein GtkGrid-Widget für den Tastenblock + // Erstellt ein GtkGrid-Widget für den Tastenblock grid = gtk_grid_new(); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); gtk_grid_set_row_spacing(GTK_GRID(grid), 5); - // Erstellen Sie 10 Buttons für die Ziffern 0-9 - for (int i = 0; i < 10; i++) { - buttons[i] = gtk_button_new_with_label(g_strdup_printf("%d", i)); + for (int i = 0; i < BUTTON_NUM; i++) { + // Erstellen der Buttons + buttons[i] = gtk_button_new_with_label(buttonlabels[i]); g_signal_connect(buttons[i], "clicked", G_CALLBACK(number_button_clicked), entry); - } - // Fügen Sie die Buttons in das Grid-Widget ein - int row = 0, column = 0; - for (int i = 0; i < 10; i++) { - gtk_grid_attach(GTK_GRID(grid), buttons[i], column, row, 1, 1); - if (column == 2) { - column = 0; - row++; - } else { - column++; - } + // Fügt die Buttons in das Grid-Widget ein + gtk_grid_attach(GTK_GRID(grid), buttons[i], i % 4, i / 4, 1, 1); } -/**/ // Erstellen Sie einen Box-Container und fügen Sie das Eingabefeld, den Button und den Tastenblock hinzu - box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(box), grid, TRUE, TRUE, 0); + box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_box_append(GTK_BOX(box), entry); + gtk_widget_set_margin_top(entry, 10); + gtk_widget_set_margin_start(entry, 10); + gtk_widget_set_margin_end(entry, 10); + + gtk_box_append(GTK_BOX(box), grid); + gtk_widget_set_halign(grid, GTK_ALIGN_CENTER); + gtk_widget_set_margin_top(grid, 10); + gtk_widget_set_margin_bottom(grid, 10); + + gtk_box_append(GTK_BOX(box), button); + gtk_widget_set_margin_start(button, 10); + gtk_widget_set_margin_end(button, 10); + gtk_widget_set_margin_bottom(button, 10); // Fügen Sie den Box-Container zum Fenster hinzu - gtk_container_add(GTK_CONTAINER(window), box); + gtk_window_set_child (GTK_WINDOW (window), box); + + gtk_window_present (GTK_WINDOW (window)); +} - // Zeigen Sie alle Widgets an - gtk_widget_show_all(window); - // Starten Sie die GTK+-Hauptschleife - gtk_main(); +int main (int argc, char **argv) +{ + GtkApplication *app; + int status; - return 0; -} + app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE); + g_signal_connect(app, "activate", G_CALLBACK (activate), NULL); + status = g_application_run (G_APPLICATION (app), argc, argv); + g_object_unref (app); + + return status; +} \ No newline at end of file diff --git a/makefile b/makefile index d9d1c9d..0f75365 100644 --- a/makefile +++ b/makefile @@ -12,27 +12,19 @@ HDRS = \ # Bibliotheken LIBS = \ - -lgtk3 + -lgtk4 # Objektdateien OBJS = $(SRCS:.c=.o) # Flagge für GTK+-Entwicklung -GTK3_CFLAGS = -Wall `pkg-config --cflags glib-2.0` \ - -I/usr/include/gtk-3.0 \ - -I/usr/include/glib-2.0 \ - -I/usr/include/pango-1.0 \ - -I/usr/include/harfbuzz \ - -I/usr/include/cairo \ - -I/usr/include/gdk-pixbuf-2.0 \ - -I/usr/include/atk-1.0 +GTK3_CFLAGS = -Wall `pkg-config --cflags gtk4` # Flagge für C-Compiler CFLAGS = $(GTK3_CFLAGS) # Flagge für Linker -LDFLAGS = `pkg-config --libs gtk+-3.0` -L/usr/local/lib -L/usr/lib -#LDFLAGS = `pkg-config --libs glib-2.0` -L/usr/local/lib -L/usr/lib +LDFLAGS = `pkg-config --libs gtk4` -L/usr/local/lib -L/usr/lib # Programmname PROGRAM = $(PROJECT) diff --git a/settings.json b/settings.json index c401ec2..6f4ac5a 100644 --- a/settings.json +++ b/settings.json @@ -1,5 +1,5 @@ { "c_cpp.includePath": [ - "/usr/include/gtk-3.0" // Ersetzen Sie diesen Pfad nach Bedarf + "/usr/include/gtk-4.0" // Ersetzen Sie diesen Pfad nach Bedarf ] } \ No newline at end of file From 55570db359926a74aef8649d6a98e42ea5de5b4b Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 27 Mar 2024 16:26:41 +0100 Subject: [PATCH 13/18] add basis for calc --- main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main.c b/main.c index c292f60..3eadf59 100644 --- a/main.c +++ b/main.c @@ -26,9 +26,11 @@ void number_button_clicked(GtkWidget *button, gpointer data) char button_char = *label; switch (button_char) { case 'C': -// gtk_entry_set_text (GTK_ENTRY(data), ""); gtk_editable_set_text(GTK_EDITABLE(data), ""); break; + case '=': + // rechne Ergebnis aus; + break; default: GtkEntryBuffer *buffer = gtk_entry_get_buffer (GTK_ENTRY(data)); gtk_entry_buffer_insert_text (buffer, -1, label, -1); From 229a0d58809d33b47ecc72d3ca2ca3c11ca76fbe Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 28 Mar 2024 15:55:39 +0100 Subject: [PATCH 14/18] wip calc logic --- .vscode/settings.json | 8 ++ GITHELP.md | 2 +- MEMO.md | 7 ++ calc.c | 249 ++++++++++++++++++++++++++++++++++++++++++ calc.h | 4 + calc.pas | 249 ++++++++++++++++++++++++++++++++++++++++++ makefile | 4 +- 7 files changed, 520 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 MEMO.md create mode 100644 calc.c create mode 100644 calc.h create mode 100644 calc.pas diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4ad980e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "files.associations": { + "stdbool.h": "c", + "cstdbool": "c", + "c++config.h": "c", + "functional": "c" + } +} \ No newline at end of file diff --git a/GITHELP.md b/GITHELP.md index 114ba87..e111a90 100644 --- a/GITHELP.md +++ b/GITHELP.md @@ -2,7 +2,7 @@ Marker : feature-keybord branch -Noch eine Änderung +https://docs.github.com/de ## Strategie diff --git a/MEMO.md b/MEMO.md new file mode 100644 index 0000000..544613d --- /dev/null +++ b/MEMO.md @@ -0,0 +1,7 @@ +# Memos + +## GUI Design + +Glade + +https://gitlab.gnome.org/GNOME/glade \ No newline at end of file diff --git a/calc.c b/calc.c new file mode 100644 index 0000000..9bf76bf --- /dev/null +++ b/calc.c @@ -0,0 +1,249 @@ +// Funktionen zum berechnen des Ergebnis + +#include +#include +#include + +#define OP_NUMBER 9 + +uint16_t FehlerPos; //: integer; +uint16_t FehlerLaenge; //: integer; +char FehlerText[512] = {0}; //: string; +void *pVari = 0; //: PVarArray; + +// Zeichen bzw. Symbole für Rechenoperation +// << Bits links schieben, >> Bits rechts schieben +// & AND, | OR, ~ XOR +const char *OpStr[OP_NUMBER] = {"+","-","*","/",">>","<<","&","|","~"}; //: array[0..8] of string = ('+','-','*','/','>>','<<','&','|','~'); + +void find_operation(char *term, char *Op, uint16_t *pPos, uint16_t p); + +/** *************************************************************************** + * Name + * + * Discription + * + * @param a Discription + * @return no + *************************************************************************** */ +bool calc_term(char *term, int64_t *result) +{ + if (!term) return false; + + if (!strlen(term)) return false; + + printf("Trimmed text [%s]\n", term); + + *result = term_disassemble(term, 0, result); + + return true; +} + + +/** *************************************************************************** + * TermZerlegung + * + * Teilt den Term in seine Bestandteile auf + * + * @param Term String des Term der entschlüsselt werden soll + * @param p Zeichenposition im gesamt Term. Dient der Fehlerausgabe + * @return Ergebnis + *************************************************************************** */ +bool term_disassemble(char *term, uint16_t p, int64_t *result) +{ + char *pPos = term; // Zeiger auf Position die verarbeitet wird + char *pEnd = term + strlen(term); // Zeiger auf Position die verarbeitet wird + int32_t i = 0; //: integer; + uint32_t n; //: integer; + uint64_t left_opp; //left operant : integer; + uint64_t right_opp; //right operant : integer; + char sTempStr[512] = {0}; //: string; + + uint64_t tempresult = 0; + + if (FehlerPos > 0) { + return false; + } + + // Trim left + while ((*pPos) && isspace(*pPos)) { + pPos++; + } + + // Trim right + while(pEnd > pPos) { + pEnd--; + if (isspace(*pEnd)) { + *(pEnd) = '\0'; + } + } + +#warning Hier weiter machen + +// p = p + strlen(term) - strlen(TrimLeft(term)); +// term = trim(term); + + i = 0; + while (i < OP_NUMBER) { + find_operation(pPos, OpStr[i], &n, p); + if (n > 0) { +// left_opp = TermZerlegung(copy(term, 1, n-1), p); +// right_opp = TermZerlegung(copy(term, n+strlen(OpStr[i]), strlen(term)-n), p+n+strlen(OpStr[i])-1); + + term_disassemble(term, p, &left_opp); + term_disassemble(term, p, &right_opp); + + switch (i) { + case 0: tempresult = left_opp + right_opp; break; + case 1: tempresult = left_opp - right_opp; break; + case 2: tempresult = left_opp * right_opp; break; + case 3: tempresult = left_opp / right_opp; break; + case 4: tempresult = left_opp >> right_opp; break; + case 5: tempresult = left_opp << right_opp; break; + case 6: tempresult = left_opp & right_opp; break; + case 7: tempresult = left_opp | right_opp; break; + case 8: tempresult = left_opp ^ right_opp; break; + default: + ; + } + return result; + } + i++; + } + + // Ist Term in Klammern + if (term[1] == '(') { + if (term[strlen(term)] == ')') { + result = TermZerlegung(trim(copy(term, 2, strlen(term)-2)), p+1); + return result; + } + } + + // Auf Variable oder Funktion prüfen + if (isalpha(term[1]) || term[1] == '_') { + i = 2; + while ((i <= strlen(term)) & (isalnum(term[1]) || term[1] == '_')) { + i++; + } + strncpy(sTempStr,term, i-1); // sTempStr = copy(term, 1, i-1); + +/* + // Auf Variablen prüfen + if (assigned(pVari)) { + for (n := low(pVari^) to high(pVari^)) { + if (lowercase(pVari^[n].Name) = lowercase(sTempStr)) { + result = pVari^[n].Wert; + return result; + } + } + } +*/ + SetFehlerMeldung('Syntax Fehler, Variable "'+sTempStr+'" unbekannt.', p, strlen(sTempStr)); + + // Auf Funktionen prüfen (z.B. Not, sin, cos) + } + + // Wenn Term eine Zahl ist + if (term[1] in ['0'..'9']) { + try + result := StrToInt(term); + except + SetFehlerMeldung('Syntax Fehler, "'+term+'" ist keine gültige Zahl.', p, strlen(term)); + end; + } + + return result; +} +// ^^ TermZerlegung ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +/** *************************************************************************** + * find_operation + * + * Sucht die Rechenopertion, und gibt die Position zurück. In Klammern wird + * nicht gesucht. + * + * @param Term Term, der nach einer Operation/Verknüpfung durchsucht werden soll + * @param Op Operation/Verknüpfung nach der in Term gesucht werden soll + * @param pPos Rückgabe der Position an der die Operation gefunden wurde + * @param p Zeichenposition im gesamt Term. Dient der Fehlerausgabe + * @return no + *************************************************************************** */ +void find_operation(char *term, char *Op, uint16_t *pPos, uint16_t p) +{ + uint16_t n = 0; //: integer; // Zeichenzähler + uint16_t k = 0; //: integer; // Klammerzähler, '(' plus 1 ; ')' minus 1 + uint16_t kPos = 0; //: integer; // Merker für Position der ersten Klammer (Fehlerausgabe) + + for (n = 1 to strlen(term)) { + if (term[n] == '(') { + if (k == 0) { + kPos = n; + } + k++; + } + if (term[n] == ')') { + dec(k); + if (k < 0) { + SetFehlerMeldung('Klammer nicht geöffnet.', p+n-1, 1); + return; + } + } + // if (k = 0) and (term[n] = Op) then + if ((k = 0) & (copy(term, n, length(Op)) = Op)) { + *pPos = n; + return; + } + } + + *pPos = 0; + if (k > 0) { + SetFehlerMeldung('Öffnende Klammer gefunden, die nicht geschlossen wird.', p+kPos-1, 1); + } +} +// ^^ find_operation ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +/** *************************************************************************** + * Name + * + * Discription + * + * @param a Discription + * @return no + *************************************************************************** */ +void SetFehlerMeldung(const char *s, uint16_t p, uint16_t l) { + FehlerPos = p; + FehlerLaenge = l; + FehlerText = s; +} + +/** *************************************************************************** + * Name + * + * Discription + * + * @param a Discription + * @return no + *************************************************************************** */ +int16_t GetFehler(uint16_t *FPos, uint16_t *FLaenge) { + int16_t result = 0; + *FPos = FehlerPos; + *FLaenge = FehlerLaenge; + if (FehlerPos > 0) { + result = -1; + } + + return result; +} + +/** *************************************************************************** + * Name + * + * Discription + * + * @param a Discription + * @return no + *************************************************************************** */ +const char *GetFehlerText() { + const char *result = FehlerText; + return result; +} diff --git a/calc.h b/calc.h new file mode 100644 index 0000000..0b271bd --- /dev/null +++ b/calc.h @@ -0,0 +1,4 @@ +#ifndef CALC_H +#define CALC_H + +#endif \ No newline at end of file diff --git a/calc.pas b/calc.pas new file mode 100644 index 0000000..51700ab --- /dev/null +++ b/calc.pas @@ -0,0 +1,249 @@ +unit IntegerTerm; + +interface + +uses SysUtils; + +type + VarRec = record + Name: string; + Wert: variant; + end; + VarArray = array of VarRec; + PVarArray = ^VarArray; + + TIntTerm = class + constructor Create(); + private + { Private-Deklarationen } + pVari: PVarArray; + FehlerPos: integer; + FehlerLaenge: integer; + FehlerText: string; + procedure FindeOperation(Term, Op: string; pPos: pinteger; p: integer); + function TermZerlegung(Term: string; p: integer): integer; + procedure SetFehlerMeldung(s: string; p: integer; l: integer); + public + { Public-Deklarationen } + function TermLoesen(Term: string; pVariablen: PVarArray): integer; + function GetFehler(FPos, FLaenge: pinteger): integer; + function GetFehlerText: string; + end; + +const + // Zeichen bzw. Symbole für Rechenoperation + // << Bits links schieben, >> Bits rechts schieben + // & AND, | OR, ~ XOR + OpStr: array[0..8] of string = ('+','-','*','/','>>','<<','&','|','~'); + +implementation + +constructor TIntTerm.Create; +begin + pVari := nil; + FehlerPos := 0; + FehlerLaenge := 0; + FehlerText := ''; +end; + +function TIntTerm.TermLoesen(Term: string; pVariablen: PVarArray): integer; +begin + FehlerPos := 0; + FehlerText := ''; + pVari := pVariablen; + result := TermZerlegung(Term, 1); +end; + +// ----------------------------------------------------------------------------- +// FindeOperation +// +// Sucht die Rechenopertion, und gibt die Position zurück. In Klammern wird +// nicht gesucht. +// +// Term : Term, der nach einer Operation/Verknüpfung durchsucht werden soll +// Op : Operation/Verknüpfung nach der in Term gesucht werden soll +// pPos : Rückgabe der Position an der die Operation gefunden wurde +// p : Zeichenposition im gesamt Term. Dient der Fehlerausgabe +// ----------------------------------------------------------------------------- +procedure TIntTerm.FindeOperation(Term: string; Op: string; pPos: pinteger; p: integer); +var + n: integer; // Zeichenzähler + k: integer; // Klammerzähler, '(' plus 1 ; ')' minus 1 + kPos: integer; // Merker für Position der ersten Klammer (Fehlerausgabe) +begin + kPos := 0; + k := 0; + for n := 1 to length(Term) do + begin + if term[n] = '(' then + begin + if k = 0 then + kPos := n; + inc(k); + end; + if term[n] = ')' then + begin + dec(k); + if k < 0 then + begin + SetFehlerMeldung('Klammer nicht geöffnet.', p+n-1, 1); + exit; + end; + end; + // if (k = 0) and (term[n] = Op) then + if (k = 0) and (copy(term, n, length(Op)) = Op) then + begin + pPos^ := n; + exit; + end; + end; + pPos^ := 0; + if k > 0 then + SetFehlerMeldung('Öffnende Klammer gefunden, die nicht geschlossen wird.', p+kPos-1, 1); +end; +// ^^ FindeOperation ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// ----------------------------------------------------------------------------- +// TermZerlegung +// +// Teilt den Term in seine Bestandteile auf +// +// Term : String des Term der entschlüsselt werden soll +// p : Zeichenposition im gesamt Term. Dient der Fehlerausgabe +// ----------------------------------------------------------------------------- +function TIntTerm.TermZerlegung(Term: string; p: integer): integer; +var + i: integer; + n: integer; + o1: integer; + o2: integer; + TempStr: string; +begin + result := 0; + + if FehlerPos > 0 then + begin + result := 1; + exit; + end; + + p := p + length(Term) - length(TrimLeft(Term)); + Term := trim(Term); + + i := 0; + while (i <= high(OpStr)) do + begin + FindeOperation(Term, OpStr[i], @n, p); + if n > 0 then + begin + o1 := TermZerlegung(copy(Term, 1, n-1), p); + o2 := TermZerlegung(copy(Term, n+length(OpStr[i]), length(Term)-n), p+n+length(OpStr[i])-1); + case i of + 0: result := o1 + o2; + 1: result := o1 - o2; + 2: result := o1 * o2; + 3: result := o1 div o2; + 4: result := o1 shr o2; + 5: result := o1 shl o2; + 6: result := o1 and o2; + 7: result := o1 or o2; + 8: result := o1 xor o2; + end; + exit; + end; + inc(i); + end; + + // Ist Term in Klammern + if Term[1] = '(' then + begin + if Term[length(Term)] = ')' then + begin + result := TermZerlegung(trim(copy(Term, 2, length(Term)-2)), p+1); + exit; + end; + end; + + // Auf Variable oder Funktion prüfen + if Term[1] in ['a'..'z','A'..'Z','_'] then + begin + i := 2; + while ((i <= length(Term)) and (Term[1] in ['a'..'z','A'..'Z','_','0'..'9'])) do + begin + inc(i); + end; + TempStr := copy(Term, 1, i-1); + + // Auf Variablen prüfen + if assigned(pVari) then + begin + for n := low(pVari^) to high(pVari^) do + begin + if lowercase(pVari^[n].Name) = lowercase(TempStr) then + begin + result := pVari^[n].Wert; + exit; + end; + end; + end; + SetFehlerMeldung('Syntax Fehler, Variable "'+TempStr+'" unbekannt.', p, length(TempStr)); + + // Auf Funktionen prüfen (z.B. Not, sin, cos) + end; + + // Wenn Term eine Zahl ist + if Term[1] in ['0'..'9'] then + begin + try + result := StrToInt(Term); + except + SetFehlerMeldung('Syntax Fehler, "'+Term+'" ist keine gültige Zahl.', p, length(Term)); + end; + exit; + end; +end; +// ^^ TermZerlegung ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +procedure TIntTerm.SetFehlerMeldung(s: string; p: integer; l: integer); +begin + FehlerPos := p; + FehlerLaenge := l; + FehlerText := s; + raise Exception.Create(s); +end; + +function TIntTerm.GetFehler(FPos: pinteger; FLaenge: pinteger): integer; +begin + result := 0; + FPos^ := FehlerPos; + FLaenge^ := FehlerLaenge; + if FehlerPos > 0 then + result := -1; +end; + +function TIntTerm.GetFehlerText(): string; +begin + result := FehlerText; +end; + + +{ +procedure TForm1.Button1Click(Sender: TObject); +var + test: VarArray; +begin + SetLength(test, 4); + test[0].Name := 'ertz'; + test[0].Wert := 25; + test[1].Name := 's34'; + test[1].Wert := 3; + test[2].Name := 'w3tz'; + test[2].Wert := 18; + test[3].Name := 'w'; + test[3].Wert := 9; + Memo1.Clear; + Memo1.Lines.Add(format('Ergebnis = %d',[TermLoesen(Edit1.Text, @test)])); +end; +} + +end. \ No newline at end of file diff --git a/makefile b/makefile index 0f75365..5f9b9f0 100644 --- a/makefile +++ b/makefile @@ -4,11 +4,11 @@ PROJECT = taschenrechner # Quellcodedateien SRCS = \ main.c \ -# button_handler.c + calc.c # Headerdateien HDRS = \ -# button_handler.h + calc.h # Bibliotheken LIBS = \ From 5db129dc857bd70e82759c475b54ff5c6c2b3bc7 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 4 Apr 2024 16:30:30 +0200 Subject: [PATCH 15/18] wip calc --- .vscode/settings.json | 3 +- MEMO.md | 14 ++- calc.c | 261 ++++++++++++++++++++++-------------------- calc.h | 17 +++ main.c | 2 + 5 files changed, 168 insertions(+), 129 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 4ad980e..f803c07 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,7 @@ "stdbool.h": "c", "cstdbool": "c", "c++config.h": "c", - "functional": "c" + "functional": "c", + "ctype.h": "c" } } \ No newline at end of file diff --git a/MEMO.md b/MEMO.md index 544613d..789f0c2 100644 --- a/MEMO.md +++ b/MEMO.md @@ -1,7 +1,19 @@ # Memos +## C Help + +https://cplusplus.com/reference/cstdlib/ + +https://www.programiz.com/c-programming/library-function/ctype.h/isalnum + ## GUI Design Glade -https://gitlab.gnome.org/GNOME/glade \ No newline at end of file +https://gitlab.gnome.org/GNOME/glade + +## Git Help + +https://git-scm.com/book/de/v2/Git-Branching-Branch-Management + +https://www.atlassian.com/de/git/tutorials/using-branches/merge-conflicts \ No newline at end of file diff --git a/calc.c b/calc.c index 9bf76bf..4e11b1a 100644 --- a/calc.c +++ b/calc.c @@ -1,158 +1,169 @@ // Funktionen zum berechnen des Ergebnis +#include #include #include #include +#include "calc.h" -#define OP_NUMBER 9 - -uint16_t FehlerPos; //: integer; -uint16_t FehlerLaenge; //: integer; -char FehlerText[512] = {0}; //: string; -void *pVari = 0; //: PVarArray; +char *termstart; +int64_t result; +//uint16_t FehlerPos; //: integer; +uint16_t FehlerNum = OK; +char FehlerText[MAX_ERROR_LEN] = {0}; //: string; +//void *pVari = 0; //: PVarArray; // Zeichen bzw. Symbole für Rechenoperation // << Bits links schieben, >> Bits rechts schieben // & AND, | OR, ~ XOR const char *OpStr[OP_NUMBER] = {"+","-","*","/",">>","<<","&","|","~"}; //: array[0..8] of string = ('+','-','*','/','>>','<<','&','|','~'); -void find_operation(char *term, char *Op, uint16_t *pPos, uint16_t p); - /** *************************************************************************** * Name * * Discription * - * @param a Discription - * @return no + * @param term Term-String, der berechnet werden soll + * @return Fehlernummer *************************************************************************** */ -bool calc_term(char *term, int64_t *result) +uint16_t calc_term(char *term) { - if (!term) return false; + result = 0; + if (!term) return ERR_TERM_EMPTY; - if (!strlen(term)) return false; + if (!strlen(term)) return ERR_TERM_EMPTY; - printf("Trimmed text [%s]\n", term); + printf("Term [%s]\n", term); - *result = term_disassemble(term, 0, result); - - return true; + termstart = term; + return term_disassemble(term, term + strlen(term) - 1, &result); } - /** *************************************************************************** - * TermZerlegung + * term_disassemble : * * Teilt den Term in seine Bestandteile auf * - * @param Term String des Term der entschlüsselt werden soll - * @param p Zeichenposition im gesamt Term. Dient der Fehlerausgabe - * @return Ergebnis + * @param term String des Term der entschlüsselt werden soll + * @param term_end Zeige auf letztes Zeichen des Terms + * @return Fehlernummer *************************************************************************** */ -bool term_disassemble(char *term, uint16_t p, int64_t *result) +uint16_t term_disassemble(char *term, char *term_end, int64_t *subresult) { char *pPos = term; // Zeiger auf Position die verarbeitet wird - char *pEnd = term + strlen(term); // Zeiger auf Position die verarbeitet wird + char *pEnd = term_end; // Zeiger auf Ende des Terms + char *pOpp = NULL; int32_t i = 0; //: integer; uint32_t n; //: integer; - uint64_t left_opp; //left operant : integer; - uint64_t right_opp; //right operant : integer; - char sTempStr[512] = {0}; //: string; + uint64_t left_opp = 0; //left operant : integer; + uint64_t right_opp = 0; //right operant : integer; uint64_t tempresult = 0; - if (FehlerPos > 0) { - return false; + if (FehlerNum != OK) { + return FehlerNum; } - // Trim left + // Trim left (find begin) while ((*pPos) && isspace(*pPos)) { pPos++; } - // Trim right + // Trim right (find end) while(pEnd > pPos) { pEnd--; - if (isspace(*pEnd)) { - *(pEnd) = '\0'; + if (!isspace(*pEnd)) { + break; } } -#warning Hier weiter machen + if (pEnd == pPos) { + // Sollte eigentlich nie auftreten + result = 0; + return OK; + } -// p = p + strlen(term) - strlen(TrimLeft(term)); -// term = trim(term); + printf("Subterm start[%d] end[%d] schar[%c] echar[%c]\n" + , (uint32_t)(pPos-termstart), (uint32_t)(pEnd-termstart), pPos, pEnd); i = 0; while (i < OP_NUMBER) { - find_operation(pPos, OpStr[i], &n, p); - if (n > 0) { -// left_opp = TermZerlegung(copy(term, 1, n-1), p); -// right_opp = TermZerlegung(copy(term, n+strlen(OpStr[i]), strlen(term)-n), p+n+strlen(OpStr[i])-1); - - term_disassemble(term, p, &left_opp); - term_disassemble(term, p, &right_opp); - - switch (i) { - case 0: tempresult = left_opp + right_opp; break; - case 1: tempresult = left_opp - right_opp; break; - case 2: tempresult = left_opp * right_opp; break; - case 3: tempresult = left_opp / right_opp; break; - case 4: tempresult = left_opp >> right_opp; break; - case 5: tempresult = left_opp << right_opp; break; - case 6: tempresult = left_opp & right_opp; break; - case 7: tempresult = left_opp | right_opp; break; - case 8: tempresult = left_opp ^ right_opp; break; - default: - ; - } - return result; + if (find_operation(pPos, OpStr[i], &pOpp)) { + if (term_disassemble(pPos, pOpp-1, &left_opp)) { + return FehlerNum; } - i++; + if (term_disassemble(pOpp+1, pEnd, &right_opp)) { + return FehlerNum; + } + + switch (i) { + case 0: tempresult = left_opp + right_opp; break; + case 1: tempresult = left_opp - right_opp; break; + case 2: tempresult = left_opp * right_opp; break; + case 3: tempresult = left_opp / right_opp; break; + case 4: tempresult = left_opp >> right_opp; break; + case 5: tempresult = left_opp << right_opp; break; + case 6: tempresult = left_opp & right_opp; break; + case 7: tempresult = left_opp | right_opp; break; + case 8: tempresult = left_opp ^ right_opp; break; + default: + ; + } + *subresult = tempresult; + return OK; + } + i++; } // Ist Term in Klammern - if (term[1] == '(') { - if (term[strlen(term)] == ')') { - result = TermZerlegung(trim(copy(term, 2, strlen(term)-2)), p+1); - return result; + if (*pPos == '(') { + if (pEnd == ')') { + printf("Klammerauflösung\n"); + if (term_disassemble(pPos+1, pEnd-1, &tempresult)) { + return FehlerNum; + } + *subresult = tempresult; + return OK; + } else { + FehlerNum = ERR_BRACKET_CLOSE; + return FehlerNum; } } // Auf Variable oder Funktion prüfen - if (isalpha(term[1]) || term[1] == '_') { - i = 2; - while ((i <= strlen(term)) & (isalnum(term[1]) || term[1] == '_')) { - i++; - } - strncpy(sTempStr,term, i-1); // sTempStr = copy(term, 1, i-1); - -/* - // Auf Variablen prüfen - if (assigned(pVari)) { - for (n := low(pVari^) to high(pVari^)) { - if (lowercase(pVari^[n].Name) = lowercase(sTempStr)) { - result = pVari^[n].Wert; - return result; - } + if (isalpha(*pPos) || *pPos == '_') { + printf("Variablenauflösung\n"); + uint16_t i = 0; + char *pVarEnd = pPos; +#warning Fehler zu langer Variablenname abfangen + while ((pVarEnd <= pEnd) && (isalnum(*pVarEnd) || *pVarEnd == '_')) { + pVarEnd++; + i++; } - } -*/ - SetFehlerMeldung('Syntax Fehler, Variable "'+sTempStr+'" unbekannt.', p, strlen(sTempStr)); - - // Auf Funktionen prüfen (z.B. Not, sin, cos) + char varName[64] = {0}; + strncpy(varName, pPos, i-1); + *pVarEnd = '\0'; + printf("Variable %s erkannt\n", varName); + + snprintf(FehlerText, MAX_ERROR_LEN, "Syntax Fehler, Variable unbekannt."); + FehlerNum = ERR_UNKNOWN_VARIABLE; + return FehlerNum; } // Wenn Term eine Zahl ist - if (term[1] in ['0'..'9']) { - try - result := StrToInt(term); - except - SetFehlerMeldung('Syntax Fehler, "'+term+'" ist keine gültige Zahl.', p, strlen(term)); - end; +// if (term[1] in ['0'..'9']) { + if (isdigit(*pPos)) { + while(isdigit(*pPos)) { + tempresult *= 10; + tempresult += *pPos & 0x0f; + } + printf("Zahl erkannt %d\n", tempresult); + } else { + FehlerNum = ERR_UNKNOWN; + return FehlerNum; } - return result; + return OK; } // ^^ TermZerlegung ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,42 +174,48 @@ bool term_disassemble(char *term, uint16_t p, int64_t *result) * nicht gesucht. * * @param Term Term, der nach einer Operation/Verknüpfung durchsucht werden soll - * @param Op Operation/Verknüpfung nach der in Term gesucht werden soll + * @param Opp Operation/Verknüpfung nach der in Term gesucht werden soll * @param pPos Rückgabe der Position an der die Operation gefunden wurde - * @param p Zeichenposition im gesamt Term. Dient der Fehlerausgabe - * @return no + * @return Fehler bool *************************************************************************** */ -void find_operation(char *term, char *Op, uint16_t *pPos, uint16_t p) +bool find_operation(char *subterm, char *Opp, char **pPos) { - uint16_t n = 0; //: integer; // Zeichenzähler - uint16_t k = 0; //: integer; // Klammerzähler, '(' plus 1 ; ')' minus 1 - uint16_t kPos = 0; //: integer; // Merker für Position der ersten Klammer (Fehlerausgabe) - - for (n = 1 to strlen(term)) { - if (term[n] == '(') { - if (k == 0) { - kPos = n; - } + uint16_t i = 0; // Zeichenzähler + uint16_t l = 0; // Merker für subterm Länge + uint16_t k = 0; // Klammerzähler, '(' plus 1 ; ')' minus 1 + +// for (n = 1; n <= strlen(subterm); n++) { + l = strlen(subterm); + while (i < l) { + if (*subterm == '(') { k++; } - if (term[n] == ')') { - dec(k); + + if (*subterm == ')') { + k--; if (k < 0) { - SetFehlerMeldung('Klammer nicht geöffnet.', p+n-1, 1); - return; + FehlerNum = ERR_BRACKET_OPEN; + snprintf(FehlerText, MAX_ERROR_LEN, "Klammer nicht geöffnet."); + return false; } } - // if (k = 0) and (term[n] = Op) then - if ((k = 0) & (copy(term, n, length(Op)) = Op)) { - *pPos = n; - return; + + if ((k = 0) && strncmp(subterm, Opp, strlen(Opp))) { + *pPos = subterm; + return true; } + i++; + subterm++; } *pPos = 0; if (k > 0) { - SetFehlerMeldung('Öffnende Klammer gefunden, die nicht geschlossen wird.', p+kPos-1, 1); + FehlerNum = ERR_BRACKET_CLOSE; + snprintf(FehlerText, MAX_ERROR_LEN, "Geöffnete Klammer gefunden, die nicht geschlossen wird."); + return false; } + + return false; } // ^^ find_operation ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -210,10 +227,8 @@ void find_operation(char *term, char *Op, uint16_t *pPos, uint16_t p) * @param a Discription * @return no *************************************************************************** */ -void SetFehlerMeldung(const char *s, uint16_t p, uint16_t l) { - FehlerPos = p; - FehlerLaenge = l; - FehlerText = s; +int64_t GetCalcValue() { + return result; } /** *************************************************************************** @@ -224,15 +239,8 @@ void SetFehlerMeldung(const char *s, uint16_t p, uint16_t l) { * @param a Discription * @return no *************************************************************************** */ -int16_t GetFehler(uint16_t *FPos, uint16_t *FLaenge) { - int16_t result = 0; - *FPos = FehlerPos; - *FLaenge = FehlerLaenge; - if (FehlerPos > 0) { - result = -1; - } - - return result; +int16_t GetFehler() { + return FehlerNum; } /** *************************************************************************** @@ -244,6 +252,5 @@ int16_t GetFehler(uint16_t *FPos, uint16_t *FLaenge) { * @return no *************************************************************************** */ const char *GetFehlerText() { - const char *result = FehlerText; - return result; + return NULL; } diff --git a/calc.h b/calc.h index 0b271bd..0eddd18 100644 --- a/calc.h +++ b/calc.h @@ -1,4 +1,21 @@ #ifndef CALC_H #define CALC_H +#define OP_NUMBER 9 +#define MAX_ERROR_LEN 512 + +enum ERROR { + OK, + ERR_UNKNOWN, + ERR_BRACKET_OPEN, + ERR_BRACKET_CLOSE, + ERR_TERM_EMPTY, + ERR_SHORT_TERM, + ERR_UNKNOWN_VARIABLE +}; + +uint16_t calc_term(char *term); +uint16_t term_disassemble(char *term, uint16_t p, int64_t *result); +bool find_operation(char *term, char *Op, uint16_t *pPos); + #endif \ No newline at end of file diff --git a/main.c b/main.c index 3eadf59..ee2f2b9 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,8 @@ #include // https://docs.gtk.org/gtk4/ +#include "calc.h" + #define BUTTON_NUM 20 GtkWidget *window; From d81bae74eb61a31ad72cbd21dd6c6dc1c628f714 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 5 Apr 2024 12:59:15 +0200 Subject: [PATCH 16/18] wip calc 2 --- calc.c | 87 +++++++++++++++++++++++++++++++++++----------------------- calc.h | 5 ++-- main.c | 6 ++++ 3 files changed, 60 insertions(+), 38 deletions(-) diff --git a/calc.c b/calc.c index 4e11b1a..2ec7712 100644 --- a/calc.c +++ b/calc.c @@ -4,9 +4,10 @@ #include #include #include +#include #include "calc.h" -char *termstart; +const char *termstart; int64_t result; //uint16_t FehlerPos; //: integer; uint16_t FehlerNum = OK; @@ -18,6 +19,9 @@ char FehlerText[MAX_ERROR_LEN] = {0}; //: string; // & AND, | OR, ~ XOR const char *OpStr[OP_NUMBER] = {"+","-","*","/",">>","<<","&","|","~"}; //: array[0..8] of string = ('+','-','*','/','>>','<<','&','|','~'); +bool find_operation(const char *pStart, const char *pEnd, const char *Opp, const char **pOpp); +uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subresult); + /** *************************************************************************** * Name * @@ -26,16 +30,24 @@ const char *OpStr[OP_NUMBER] = {"+","-","*","/",">>","<<","&","|","~"}; //: * @param term Term-String, der berechnet werden soll * @return Fehlernummer *************************************************************************** */ -uint16_t calc_term(char *term) +uint16_t calc_term(const char *term) { result = 0; - if (!term) return ERR_TERM_EMPTY; - - if (!strlen(term)) return ERR_TERM_EMPTY; + FehlerNum = OK; + if (!term) { + FehlerNum = ERR_TERM_EMPTY; + return FehlerNum; + } - printf("Term [%s]\n", term); + if (!strlen(term)) { + FehlerNum = ERR_TERM_EMPTY; + return FehlerNum; + } termstart = term; + + printf("Start Term [%s] %p %p \n", term, term, term + strlen(term)); + return term_disassemble(term, term + strlen(term) - 1, &result); } @@ -48,17 +60,17 @@ uint16_t calc_term(char *term) * @param term_end Zeige auf letztes Zeichen des Terms * @return Fehlernummer *************************************************************************** */ -uint16_t term_disassemble(char *term, char *term_end, int64_t *subresult) +uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subresult) { - char *pPos = term; // Zeiger auf Position die verarbeitet wird - char *pEnd = term_end; // Zeiger auf Ende des Terms - char *pOpp = NULL; + const char *pPos = term; // Zeiger auf Position die verarbeitet wird + const char *pEnd = term_end; // Zeiger auf Ende des Terms + const char *pOpp = NULL; int32_t i = 0; //: integer; - uint32_t n; //: integer; - uint64_t left_opp = 0; //left operant : integer; - uint64_t right_opp = 0; //right operant : integer; + int64_t left_opp = 0; //left operant : integer; + int64_t right_opp = 0; //right operant : integer; + int64_t tempresult = 0; - uint64_t tempresult = 0; + printf("Sub Term 1 [%ld] [%ld] \n", pPos-termstart, pEnd-termstart); if (FehlerNum != OK) { return FehlerNum; @@ -69,14 +81,18 @@ uint16_t term_disassemble(char *term, char *term_end, int64_t *subresult) pPos++; } + printf("Sub Term 2 [%ld] [%ld] \n", pPos-termstart, pEnd-termstart); + // Trim right (find end) while(pEnd > pPos) { - pEnd--; if (!isspace(*pEnd)) { break; } + pEnd--; } + printf("Sub Term 3 [%ld] [%ld] \n", pPos-termstart, pEnd-termstart); + if (pEnd == pPos) { // Sollte eigentlich nie auftreten result = 0; @@ -84,11 +100,12 @@ uint16_t term_disassemble(char *term, char *term_end, int64_t *subresult) } printf("Subterm start[%d] end[%d] schar[%c] echar[%c]\n" - , (uint32_t)(pPos-termstart), (uint32_t)(pEnd-termstart), pPos, pEnd); + , (uint16_t)(pPos-termstart), (uint16_t)(pEnd-termstart), (char)*pPos, (char)*pEnd); i = 0; while (i < OP_NUMBER) { - if (find_operation(pPos, OpStr[i], &pOpp)) { + if (find_operation(pPos, pEnd, OpStr[i], &pOpp)) { + printf("Operation erkannt [%s] Pos[%d]", OpStr[i], (uint16_t)(pOpp-termstart)); if (term_disassemble(pPos, pOpp-1, &left_opp)) { return FehlerNum; } @@ -117,7 +134,7 @@ uint16_t term_disassemble(char *term, char *term_end, int64_t *subresult) // Ist Term in Klammern if (*pPos == '(') { - if (pEnd == ')') { + if (*pEnd == ')') { printf("Klammerauflösung\n"); if (term_disassemble(pPos+1, pEnd-1, &tempresult)) { return FehlerNum; @@ -134,7 +151,8 @@ uint16_t term_disassemble(char *term, char *term_end, int64_t *subresult) if (isalpha(*pPos) || *pPos == '_') { printf("Variablenauflösung\n"); uint16_t i = 0; - char *pVarEnd = pPos; + char *pVarEnd; + pVarEnd = (char*)pPos; #warning Fehler zu langer Variablenname abfangen while ((pVarEnd <= pEnd) && (isalnum(*pVarEnd) || *pVarEnd == '_')) { pVarEnd++; @@ -151,13 +169,14 @@ uint16_t term_disassemble(char *term, char *term_end, int64_t *subresult) } // Wenn Term eine Zahl ist -// if (term[1] in ['0'..'9']) { if (isdigit(*pPos)) { - while(isdigit(*pPos)) { + while(isdigit(*pPos) && pPos <= pEnd) { tempresult *= 10; tempresult += *pPos & 0x0f; + pPos++; } - printf("Zahl erkannt %d\n", tempresult); + printf("Zahl erkannt %ld\n", tempresult); + result = tempresult; } else { FehlerNum = ERR_UNKNOWN; return FehlerNum; @@ -176,22 +195,20 @@ uint16_t term_disassemble(char *term, char *term_end, int64_t *subresult) * @param Term Term, der nach einer Operation/Verknüpfung durchsucht werden soll * @param Opp Operation/Verknüpfung nach der in Term gesucht werden soll * @param pPos Rückgabe der Position an der die Operation gefunden wurde - * @return Fehler bool + * @return true wenn Rechenoperation gefunden *************************************************************************** */ -bool find_operation(char *subterm, char *Opp, char **pPos) +//bool find_operation(const char *subterm, const char *Opp, const char **pPos) +bool find_operation(const char *pPos, const char *pEnd, const char *Opp, const char **pOpp) { uint16_t i = 0; // Zeichenzähler - uint16_t l = 0; // Merker für subterm Länge uint16_t k = 0; // Klammerzähler, '(' plus 1 ; ')' minus 1 -// for (n = 1; n <= strlen(subterm); n++) { - l = strlen(subterm); - while (i < l) { - if (*subterm == '(') { + while (pPos <= pEnd) { + if (*pPos == '(') { k++; } - if (*subterm == ')') { + if (*pPos == ')') { k--; if (k < 0) { FehlerNum = ERR_BRACKET_OPEN; @@ -200,15 +217,15 @@ bool find_operation(char *subterm, char *Opp, char **pPos) } } - if ((k = 0) && strncmp(subterm, Opp, strlen(Opp))) { - *pPos = subterm; + if ((k = 0) && strncmp(pPos, Opp, strlen(Opp))) { + *pOpp = pPos; return true; } i++; - subterm++; + pPos++; } - *pPos = 0; + pOpp = NULL; if (k > 0) { FehlerNum = ERR_BRACKET_CLOSE; snprintf(FehlerText, MAX_ERROR_LEN, "Geöffnete Klammer gefunden, die nicht geschlossen wird."); @@ -227,7 +244,7 @@ bool find_operation(char *subterm, char *Opp, char **pPos) * @param a Discription * @return no *************************************************************************** */ -int64_t GetCalcValue() { +int64_t get_calc_result() { return result; } diff --git a/calc.h b/calc.h index 0eddd18..d52d6d9 100644 --- a/calc.h +++ b/calc.h @@ -14,8 +14,7 @@ enum ERROR { ERR_UNKNOWN_VARIABLE }; -uint16_t calc_term(char *term); -uint16_t term_disassemble(char *term, uint16_t p, int64_t *result); -bool find_operation(char *term, char *Op, uint16_t *pPos); +uint16_t calc_term(const char *term); +int64_t get_calc_result(); #endif \ No newline at end of file diff --git a/main.c b/main.c index ee2f2b9..5c99823 100644 --- a/main.c +++ b/main.c @@ -32,6 +32,12 @@ void number_button_clicked(GtkWidget *button, gpointer data) break; case '=': // rechne Ergebnis aus; + const char *term = gtk_editable_get_text(GTK_EDITABLE(data)); + if (!calc_term(term)) { + printf("Kein Fehler. Ergebnis : %ld\n", get_calc_result()); + } else { + printf("Fehler aufgetreten\n"); + } break; default: GtkEntryBuffer *buffer = gtk_entry_get_buffer (GTK_ENTRY(data)); From 7b55f78c3cfcb3e0c975995eee49a6c9b7f7af5d Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 8 Apr 2024 12:11:39 +0200 Subject: [PATCH 17/18] grundlegende berechnung --- calc.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/calc.c b/calc.c index 2ec7712..7e9c0df 100644 --- a/calc.c +++ b/calc.c @@ -77,7 +77,7 @@ uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subre } // Trim left (find begin) - while ((*pPos) && isspace(*pPos)) { + while (isspace(*pPos)) { pPos++; } @@ -93,19 +93,13 @@ uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subre printf("Sub Term 3 [%ld] [%ld] \n", pPos-termstart, pEnd-termstart); - if (pEnd == pPos) { - // Sollte eigentlich nie auftreten - result = 0; - return OK; - } - printf("Subterm start[%d] end[%d] schar[%c] echar[%c]\n" , (uint16_t)(pPos-termstart), (uint16_t)(pEnd-termstart), (char)*pPos, (char)*pEnd); i = 0; while (i < OP_NUMBER) { if (find_operation(pPos, pEnd, OpStr[i], &pOpp)) { - printf("Operation erkannt [%s] Pos[%d]", OpStr[i], (uint16_t)(pOpp-termstart)); + printf("Operation erkannt [%s] Pos[%d]\n", OpStr[i], (uint16_t)(pOpp-termstart)); if (term_disassemble(pPos, pOpp-1, &left_opp)) { return FehlerNum; } @@ -113,6 +107,8 @@ uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subre return FehlerNum; } + printf("Rechen Operanten %ld %s %ld\n", left_opp, OpStr[i], right_opp); + switch (i) { case 0: tempresult = left_opp + right_opp; break; case 1: tempresult = left_opp - right_opp; break; @@ -126,6 +122,7 @@ uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subre default: ; } + printf("Zwischenergebnis %ld\n", tempresult); *subresult = tempresult; return OK; } @@ -168,6 +165,11 @@ uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subre return FehlerNum; } + // Wenn mit Komma beginnt = 0,xx + if (*pPos == ',') { + + } + // Wenn Term eine Zahl ist if (isdigit(*pPos)) { while(isdigit(*pPos) && pPos <= pEnd) { @@ -176,7 +178,7 @@ uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subre pPos++; } printf("Zahl erkannt %ld\n", tempresult); - result = tempresult; + *subresult = tempresult; } else { FehlerNum = ERR_UNKNOWN; return FehlerNum; @@ -209,15 +211,16 @@ bool find_operation(const char *pPos, const char *pEnd, const char *Opp, const c } if (*pPos == ')') { - k--; - if (k < 0) { + if (k == 0) { FehlerNum = ERR_BRACKET_OPEN; snprintf(FehlerText, MAX_ERROR_LEN, "Klammer nicht geöffnet."); return false; } + k--; } - if ((k = 0) && strncmp(pPos, Opp, strlen(Opp))) { + if ((k == 0) && !strncmp(pPos, Opp, strlen(Opp))) { + printf("Find Opp start[%d] end[%d] Opp[%s]\n", (uint16_t)(pPos-termstart), (uint16_t)(pEnd-termstart), Opp); *pOpp = pPos; return true; } @@ -225,7 +228,6 @@ bool find_operation(const char *pPos, const char *pEnd, const char *Opp, const c pPos++; } - pOpp = NULL; if (k > 0) { FehlerNum = ERR_BRACKET_CLOSE; snprintf(FehlerText, MAX_ERROR_LEN, "Geöffnete Klammer gefunden, die nicht geschlossen wird."); From 306fae42e21d98ac39ad095cdc637f346c5e7eca Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 8 Apr 2024 13:51:17 +0200 Subject: [PATCH 18/18] wip vorzeichen --- calc.c | 30 +++++++++++++++++++++++++----- calc.h | 5 +++-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/calc.c b/calc.c index 7e9c0df..5369f98 100644 --- a/calc.c +++ b/calc.c @@ -77,14 +77,14 @@ uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subre } // Trim left (find begin) - while (isspace(*pPos)) { + while (isspace(*pPos) && (pPos < pEnd)) { pPos++; } printf("Sub Term 2 [%ld] [%ld] \n", pPos-termstart, pEnd-termstart); // Trim right (find end) - while(pEnd > pPos) { + while(pPos <= pEnd) { if (!isspace(*pEnd)) { break; } @@ -93,15 +93,26 @@ uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subre printf("Sub Term 3 [%ld] [%ld] \n", pPos-termstart, pEnd-termstart); + if (pPos > pEnd) { + // Leerer Term + return WARN_EMPTY_TERM; + } + + printf("Sub Term 4 [%ld] [%ld] \n", pPos-termstart, pEnd-termstart); + printf("Subterm start[%d] end[%d] schar[%c] echar[%c]\n" , (uint16_t)(pPos-termstart), (uint16_t)(pEnd-termstart), (char)*pPos, (char)*pEnd); i = 0; + uint16_t err = 0; while (i < OP_NUMBER) { if (find_operation(pPos, pEnd, OpStr[i], &pOpp)) { printf("Operation erkannt [%s] Pos[%d]\n", OpStr[i], (uint16_t)(pOpp-termstart)); - if (term_disassemble(pPos, pOpp-1, &left_opp)) { - return FehlerNum; + err = term_disassemble(pPos, pOpp-1, &left_opp); + if (err) { + if (err != WARN_EMPTY_TERM || *OpStr[i] != '-') { + return FehlerNum; + } } if (term_disassemble(pOpp+1, pEnd, &right_opp)) { return FehlerNum; @@ -111,7 +122,16 @@ uint16_t term_disassemble(const char *term, const char *term_end, int64_t *subre switch (i) { case 0: tempresult = left_opp + right_opp; break; - case 1: tempresult = left_opp - right_opp; break; + case 1: + if (err == WARN_EMPTY_TERM) { + // Vorzeichen + tempresult = right_opp * -1; + } else { + // Rechenoperation + tempresult = left_opp - right_opp; + } + break; + case 2: tempresult = left_opp * right_opp; break; case 3: tempresult = left_opp / right_opp; break; case 4: tempresult = left_opp >> right_opp; break; diff --git a/calc.h b/calc.h index d52d6d9..bf83b36 100644 --- a/calc.h +++ b/calc.h @@ -5,13 +5,14 @@ #define MAX_ERROR_LEN 512 enum ERROR { - OK, + OK = 0, ERR_UNKNOWN, ERR_BRACKET_OPEN, ERR_BRACKET_CLOSE, ERR_TERM_EMPTY, ERR_SHORT_TERM, - ERR_UNKNOWN_VARIABLE + ERR_UNKNOWN_VARIABLE, + WARN_EMPTY_TERM }; uint16_t calc_term(const char *term);