From 678836ee7f2b57c38729b3453885f5bcadc7ef7d Mon Sep 17 00:00:00 2001 From: mquinson Date: Sun, 16 Jul 2006 14:17:00 +0000 Subject: [PATCH] Lesson 6 added git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2590 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- doc/Doxyfile.in | 1 + doc/gtut-files/.cvsignore | 9 +++ doc/gtut-files/1-bones.output | 5 +- doc/gtut-files/3-args.output | 5 +- doc/gtut-files/4-callback.output | 7 +- doc/gtut-files/5-globals.c | 6 +- doc/gtut-files/5-globals.output | 11 ++- doc/gtut-files/6-logs.c | 80 ++++++++++++++++++++ doc/gtut-files/6-logs.output | 19 +++++ doc/gtut-files/6-logs.output.error | 6 ++ doc/gtut-files/6-logs.output.verbose | 21 ++++++ doc/gtut-files/Makefile | 66 +++++++++++++++-- doc/gtut-main.doc | 7 ++ doc/gtut-tour-5-globals.doc | 2 +- doc/gtut-tour-6-logs.doc | 107 +++++++++++++++++++++++++++ doc/gtut-tour.doc | 2 + 16 files changed, 331 insertions(+), 23 deletions(-) create mode 100644 doc/gtut-files/6-logs.c create mode 100644 doc/gtut-files/6-logs.output create mode 100644 doc/gtut-files/6-logs.output.error create mode 100644 doc/gtut-files/6-logs.output.verbose create mode 100644 doc/gtut-tour-6-logs.doc diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 290202ff3c..f83edce07b 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -414,6 +414,7 @@ INPUT = @srcdir@/index.doc \ @srcdir@/gtut-tour-3-args.doc \ @srcdir@/gtut-tour-4-callback.doc \ @srcdir@/gtut-tour-5-globals.doc \ + @srcdir@/gtut-tour-6-logs.doc \ \ ./logcategories.doc \ \ diff --git a/doc/gtut-files/.cvsignore b/doc/gtut-files/.cvsignore index e2e2946055..6449498351 100644 --- a/doc/gtut-files/.cvsignore +++ b/doc/gtut-files/.cvsignore @@ -42,3 +42,12 @@ _4-callback_simulator.c _5-globals_client.c _5-globals_server.c _5-globals_simulator.c + +6-logs.mk +6-logs.trace +6-logs_client +6-logs_server +6-logs_simulator +_6-logs_client.c +_6-logs_server.c +_6-logs_simulator.c diff --git a/doc/gtut-files/1-bones.output b/doc/gtut-files/1-bones.output index 046ad734b8..d5ce9ce134 100644 --- a/doc/gtut-files/1-bones.output +++ b/doc/gtut-files/1-bones.output @@ -1,7 +1,8 @@ $ ./test_client -[blaise:client:(6328) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS +[blaise:client:(3539) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS $ ./test_server -[blaise:server:(6331) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS +[blaise:server:(3542) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS +$ $ ./test_simulator platform.xml test.xml [Jacquelin:server:(1) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS [Boivin:client:(2) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS diff --git a/doc/gtut-files/3-args.output b/doc/gtut-files/3-args.output index 42084bce4a..7b36ec6179 100644 --- a/doc/gtut-files/3-args.output +++ b/doc/gtut-files/3-args.output @@ -1,9 +1,10 @@ $ ./test_server 12345 & ./test_client 127.0.0.1 12345 Client ready; listening on 1024 That's it, we sent the data to the server on 127.0.0.1 -[blaise:client:(6454) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS +[blaise:client:(3668) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS Cool, we received the message from 127.0.0.1:1024. -[blaise:server:(6452) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS +[blaise:server:(3666) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS +$ $ ./test_simulator platform.xml test.xml Client ready; listening on 1024 That's it, we sent the data to the server on Jacquelin diff --git a/doc/gtut-files/4-callback.output b/doc/gtut-files/4-callback.output index 36c3e29c0e..7aef7fe7c4 100644 --- a/doc/gtut-files/4-callback.output +++ b/doc/gtut-files/4-callback.output @@ -1,9 +1,10 @@ -$ ./test_server 12345 & ./test_client 127.0.0.1 12345 +$ ./test_server 23451 & ./test_client 127.0.0.1 23451 Client ready; listening on 1024 That's it, we sent the data to the server on 127.0.0.1 -[blaise:client:(7454) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS +[blaise:client:(3770) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS Cool, we received the message from 127.0.0.1:1024. -[blaise:server:(7452) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS +[blaise:server:(3768) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS +$ $ ./test_simulator platform.xml test.xml Client ready; listening on 1024 That's it, we sent the data to the server on Jacquelin diff --git a/doc/gtut-files/5-globals.c b/doc/gtut-files/5-globals.c index 3f551f408d..9ca9c17620 100644 --- a/doc/gtut-files/5-globals.c +++ b/doc/gtut-files/5-globals.c @@ -2,7 +2,7 @@ typedef struct { int killed; -} *server_data_t; +} server_data_t; int server_kill_cb(gras_msg_cb_ctx_t ctx, void *payload) { @@ -28,11 +28,11 @@ int server_hello_cb(gras_msg_cb_ctx_t ctx, void *payload) { int server(int argc, char *argv[]) { gras_socket_t mysock; /* socket on which I listen */ - server_data_t globals; + server_data_t *globals; gras_init(&argc,argv); - globals=gras_userdata_new(server_data_t); + globals=gras_userdata_new(server_data_t*); globals->killed=0; gras_msgtype_declare("hello", NULL); diff --git a/doc/gtut-files/5-globals.output b/doc/gtut-files/5-globals.output index d212c62e4a..6535d4e1cf 100644 --- a/doc/gtut-files/5-globals.output +++ b/doc/gtut-files/5-globals.output @@ -3,9 +3,11 @@ Client ready; listening on 1024 we sent the data to the server on 127.0.0.1. Let's do it again for fun Ok. Enough. Have a rest, and then kill the server Cool, we received the message from 127.0.0.1:1024. -[blaise:client:(18581) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS +[blaise:client:(3874) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS Cool, we received the message from 127.0.0.1:1024. Argh, killed by 127.0.0.1:1024! Bye folks... +[blaise:server:(3872) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS +$ $ ./test_simulator platform.xml test.xml Client ready; listening on 1024 we sent the data to the server on Jacquelin. Let's do it again for fun @@ -14,9 +16,6 @@ Ok. Enough. Have a rest, and then kill the server Cool, we received the message from Boivin:1024. [Boivin:client:(2) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS Argh, killed by Boivin:1024! Bye folks... -[0.000000] msg/global.c:478: [msg_kernel/INFO] Oops ! Deadlock or code not perfectly clean. -[0.000000] msg/global.c:293: [msg_kernel/INFO] MSG: 1 processes are still running, waiting for something. -[0.000000] msg/global.c:295: [msg_kernel/INFO] MSG: () on : . -[0.000000] msg/global.c:309: [msg_kernel/INFO] MSG: server(1) on Jacquelin: [blocked] Listening on channel 0 -[0.000000] msg/global.c:486: [msg_kernel/INFO] Return a Warning. +[Jacquelin:server:(1) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS +[0.000000] msg/global.c:475: [msg_kernel/INFO] Congratulations ! Simulation terminated : all process are over $ diff --git a/doc/gtut-files/6-logs.c b/doc/gtut-files/6-logs.c new file mode 100644 index 0000000000..1fff408adf --- /dev/null +++ b/doc/gtut-files/6-logs.c @@ -0,0 +1,80 @@ +#include + +XBT_LOG_NEW_DEFAULT_CATEGORY(test,"My little example"); + +typedef struct { + int killed; +} server_data_t; + + +int server_kill_cb(gras_msg_cb_ctx_t ctx, void *payload) { + gras_socket_t client = gras_msg_cb_ctx_from(ctx); + server_data_t *globals=(server_data_t*)gras_userdata_get(); + + CRITICAL2("Argh, killed by %s:%d! Bye folks...", + gras_socket_peer_name(client), gras_socket_peer_port(client)); + + globals->killed = 1; + + return 1; +} /* end_of_kill_callback */ + +int server_hello_cb(gras_msg_cb_ctx_t ctx, void *payload) { + gras_socket_t client = gras_msg_cb_ctx_from(ctx); + + INFO2("Cool, we received the message from %s:%d.", + gras_socket_peer_name(client), gras_socket_peer_port(client)); + + return 1; +} /* end_of_hello_callback */ + +int server(int argc, char *argv[]) { + gras_socket_t mysock; /* socket on which I listen */ + server_data_t *globals; + + gras_init(&argc,argv); + + globals=gras_userdata_new(server_data_t*); + globals->killed=0; + + gras_msgtype_declare("hello", NULL); + gras_msgtype_declare("kill", NULL); + mysock = gras_socket_server(atoi(argv[1])); + + gras_cb_register(gras_msgtype_by_name("hello"),&server_hello_cb); + gras_cb_register(gras_msgtype_by_name("kill"),&server_kill_cb); + + while (!globals->killed) { + gras_msg_handle(-1); /* blocking */ + } + + gras_exit(); + return 0; +} + +int client(int argc, char *argv[]) { + gras_socket_t mysock; /* socket on which I listen */ + gras_socket_t toserver; /* socket used to write to the server */ + + gras_init(&argc,argv); + + gras_msgtype_declare("hello", NULL); + gras_msgtype_declare("kill", NULL); + mysock = gras_socket_server_range(1024, 10000, 0, 0); + + VERB1("Client ready; listening on %d", gras_socket_my_port(mysock)); + + gras_os_sleep(1.5); /* sleep 1 second and half */ + toserver = gras_socket_client(argv[1], atoi(argv[2])); + + gras_msg_send(toserver,gras_msgtype_by_name("hello"), NULL); + INFO1("we sent the data to the server on %s. Let's do it again for fun", gras_socket_peer_name(toserver)); + gras_msg_send(toserver,gras_msgtype_by_name("hello"), NULL); + + INFO0("Ok. Enough. Have a rest, and then kill the server"); + gras_os_sleep(5); /* sleep 1 second and half */ + gras_msg_send(toserver,gras_msgtype_by_name("kill"), NULL); + + gras_exit(); + return 0; +} diff --git a/doc/gtut-files/6-logs.output b/doc/gtut-files/6-logs.output new file mode 100644 index 0000000000..f1d97d4c7f --- /dev/null +++ b/doc/gtut-files/6-logs.output @@ -0,0 +1,19 @@ +$ ./test_server 12345 & ./test_client 127.0.0.1 12345 +[blaise:client:(15633) 0.000005] test.c:71: [test/INFO] we sent the data to the server on 127.0.0.1. Let's do it again for fun +[blaise:client:(15633) 0.000071] test.c:74: [test/INFO] Ok. Enough. Have a rest, and then kill the server +[blaise:client:(15633) 5.008669] gras/gras.c:79: [gras/INFO] Exiting GRAS +[blaise:server:(15630) 0.000005] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024. +[blaise:server:(15630) 5.008181] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024. +[blaise:server:(15630) 5.008226] test.c:15: [test/CRITICAL] Argh, killed by 127.0.0.1:1024! Bye folks... +[blaise:server:(15630) 5.008245] gras/gras.c:79: [gras/INFO] Exiting GRAS +$ +$ ./test_simulator platform.xml test.xml +[Boivin:client:(2) 0.000000] test.c:71: [test/INFO] we sent the data to the server on Jacquelin. Let's do it again for fun +[Jacquelin:server:(1) 0.000000] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024. +[Boivin:client:(2) 0.000537] test.c:74: [test/INFO] Ok. Enough. Have a rest, and then kill the server +[Jacquelin:server:(1) 0.000537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024. +[Boivin:client:(2) 5.001074] gras/gras.c:79: [gras/INFO] Exiting GRAS +[Jacquelin:server:(1) 5.001074] test.c:15: [test/CRITICAL] Argh, killed by Boivin:1024! Bye folks... +[Jacquelin:server:(1) 5.001074] gras/gras.c:79: [gras/INFO] Exiting GRAS +[5.001074] msg/global.c:475: [msg_kernel/INFO] Congratulations ! Simulation terminated : all process are over +$ diff --git a/doc/gtut-files/6-logs.output.error b/doc/gtut-files/6-logs.output.error new file mode 100644 index 0000000000..c9a05eac29 --- /dev/null +++ b/doc/gtut-files/6-logs.output.error @@ -0,0 +1,6 @@ +$ ./test_server 12345 --gras-log=root.thres=error & ./test_client 127.0.0.1 12345 --gras-log=root.thres=error +[blaise:server:(15511) 0.000005] test.c:15: [test/CRITICAL] Argh, killed by 127.0.0.1:1024! Bye folks... +$ +$ ./test_simulator platform.xml test.xml --gras-log=root.thres=error +[Jacquelin:server:(1) 0.000000] test.c:15: [test/CRITICAL] Argh, killed by Boivin:1024! Bye folks... +$ diff --git a/doc/gtut-files/6-logs.output.verbose b/doc/gtut-files/6-logs.output.verbose new file mode 100644 index 0000000000..cbada39562 --- /dev/null +++ b/doc/gtut-files/6-logs.output.verbose @@ -0,0 +1,21 @@ +$ ./test_server 12345 --gras-log=test.thres=verbose & ./test_client 127.0.0.1 12345 --gras-log=test.thres=verbose +[blaise:client:(12057) 0.000005] test.c:65: [test/VERBOSE] Client ready; listening on 1024 +[blaise:client:(12057) 1.506727] test.c:71: [test/INFO] we sent the data to the server on 127.0.0.1. Let's do it again for fun +[blaise:client:(12057) 1.506758] test.c:74: [test/INFO] Ok. Enough. Have a rest, and then kill the server +[blaise:client:(12057) 6.735174] gras/gras.c:79: [gras/INFO] Exiting GRAS +[blaise:server:(12054) 0.000004] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024. +[blaise:server:(12054) 5.228655] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024. +[blaise:server:(12054) 5.228698] test.c:15: [test/CRITICAL] Argh, killed by 127.0.0.1:1024! Bye folks... +[blaise:server:(12054) 5.228716] gras/gras.c:79: [gras/INFO] Exiting GRAS +$ +$ ./test_simulator platform.xml test.xml --gras-log=test.thres=verbose +[Boivin:client:(2) 0.000000] test.c:65: [test/VERBOSE] Client ready; listening on 1024 +[Boivin:client:(2) 1.500537] test.c:71: [test/INFO] we sent the data to the server on Jacquelin. Let's do it again for fun +[Jacquelin:server:(1) 1.500537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024. +[Boivin:client:(2) 1.501074] test.c:74: [test/INFO] Ok. Enough. Have a rest, and then kill the server +[Jacquelin:server:(1) 1.501074] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024. +[Boivin:client:(2) 6.501611] gras/gras.c:79: [gras/INFO] Exiting GRAS +[Jacquelin:server:(1) 6.501611] test.c:15: [test/CRITICAL] Argh, killed by Boivin:1024! Bye folks... +[Jacquelin:server:(1) 6.501611] gras/gras.c:79: [gras/INFO] Exiting GRAS +[6.501611] msg/global.c:475: [msg_kernel/INFO] Congratulations ! Simulation terminated : all process are over +$ diff --git a/doc/gtut-files/Makefile b/doc/gtut-files/Makefile index 3e31aa606a..ca8f5e7bf3 100644 --- a/doc/gtut-files/Makefile +++ b/doc/gtut-files/Makefile @@ -2,10 +2,10 @@ export LD_LIBRARY_PATH=$(GRAS_ROOT)/lib all: 1-bones.output 2-simple.output 3-args.output 4-callback.output \ - 5-globals.output + 5-globals.output 6-logs.output veryclean: clean - rm *.output + rm *.output* # Lesson 1: simple bones of project ######################################## @@ -15,6 +15,7 @@ veryclean: clean ./1-bones_client >> $@ 2>&1 echo '$$ ./test_server' >> $@ ./1-bones_server >> $@ 2>&1 + echo '$$' >> $@ echo '$$ ./test_simulator platform.xml test.xml' >> $@ ./1-bones_simulator gtut-platform.xml test.xml >> $@ 2>&1 echo '$$' >> $@ @@ -55,9 +56,11 @@ clean:: ./3-args_server 12345 >> $@ 2>&1& ./3-args_client 127.0.0.1 12345 >> $@ 2>&1 sleep 1 + echo '$$' >> $@ echo '$$ ./test_simulator platform.xml test.xml' >> $@ ./3-args_simulator gtut-platform.xml 3-args.xml >> $@ 2>&1 echo '$$' >> $@ + killall 3-args_server 3-args_client 2>/dev/null || true 3-args_client 3-args_server 3-args_simulator: _3-args_client.c _3-args_server.c _3-args_simulator.c make -f 3-args.mk @@ -73,13 +76,15 @@ clean:: ######################################## 4-callback.output: 4-callback_client 4-callback_server 4-callback_simulator - echo '$$ ./test_server 12345 & ./test_client 127.0.0.1 12345' > $@ - ./4-callback_server 12345 >> $@ 2>&1& - ./4-callback_client 127.0.0.1 12345 >> $@ 2>&1 + echo '$$ ./test_server 23451 & ./test_client 127.0.0.1 23451' > $@ + ./4-callback_server 23451 >> $@ 2>&1& + ./4-callback_client 127.0.0.1 23451 >> $@ 2>&1 sleep 1 + echo '$$' >> $@ echo '$$ ./test_simulator platform.xml test.xml' >> $@ ./4-callback_simulator gtut-platform.xml 3-args.xml >> $@ 2>&1 - echo '$$' >> $@ + echo '$$' >> $@ + killall 4-callback_server 4-callback_client 2>/dev/null || true 4-callback_client 4-callback_server 4-callback_simulator: _4-callback_client.c _4-callback_server.c _4-callback_simulator.c make -f 4-callback.mk @@ -99,9 +104,11 @@ clean:: ./5-globals_server 12345 >> $@ 2>&1& ./5-globals_client 127.0.0.1 12345 >> $@ 2>&1 sleep 1 + echo '$$' >> $@ echo '$$ ./test_simulator platform.xml test.xml' >> $@ ./5-globals_simulator gtut-platform.xml 3-args.xml >> $@ 2>&1 echo '$$' >> $@ + killall 5-globals_server 5-globals_client 2>/dev/null || true 5-globals_client 5-globals_server 5-globals_simulator: _5-globals_client.c _5-globals_server.c _5-globals_simulator.c make -f 5-globals.mk @@ -113,3 +120,50 @@ clean:: if [ -e 5-globals.mk ] ; then make -f 5-globals.mk clean; fi rm -f _5-globals_client.c _5-globals_server.c _5-globals_simulator.c 5-globals.trace 5-globals.mk +# Lesson 6: logs +######################################## + +6-logs.output: 6-logs_client 6-logs_server 6-logs_simulator 6-logs.output.verbose 6-logs.output.error + echo '$$ ./test_server 12345 & ./test_client 127.0.0.1 12345' > $@ + ./6-logs_server 12345 2>&1 |sed s/6-logs/test/ >> $@ 2>&1& + ./6-logs_client 127.0.0.1 12345 2>&1 |sed s/6-logs/test/ >> $@ 2>&1 + sleep 1 + echo '$$' >> $@ + echo '$$ ./test_simulator platform.xml test.xml' >> $@ + ./6-logs_simulator gtut-platform.xml 3-args.xml 2>&1 |sed s/6-logs/test/ >> $@ 2>&1 + echo '$$' >> $@ + killall 6-logs_server 6-logs_client 2>/dev/null || true + +6-logs.output.verbose: 6-logs_client 6-logs_server 6-logs_simulator + echo '$$ ./test_server 12345 --gras-log=test.thres=verbose & ./test_client 127.0.0.1 12345 --gras-log=test.thres=verbose' > $@ + ./6-logs_server 12345 --gras-log=test.thres=verbose 2>&1 |sed s/6-logs/test/ >> $@ 2>&1& + ./6-logs_client 127.0.0.1 12345 --gras-log=test.thres=verbose 2>&1 |sed s/6-logs/test/ >> $@ 2>&1 + sleep 1 + echo '$$' >> $@ + echo '$$ ./test_simulator platform.xml test.xml --gras-log=test.thres=verbose' >> $@ + ./6-logs_simulator gtut-platform.xml 3-args.xml --gras-log=test.thres=verbose 2>&1 |sed s/6-logs/test/ >> $@ 2>&1 + echo '$$' >> $@ + killall 6-logs_server 6-logs_client 2>/dev/null || true + +6-logs.output.error: 6-logs_client 6-logs_server 6-logs_simulator + echo '$$ ./test_server 12345 --gras-log=root.thres=error & ./test_client 127.0.0.1 12345 --gras-log=root.thres=error' > $@ + ./6-logs_server 12345 --gras-log=root.thres=error 2>&1 |sed s/6-logs/test/ >> $@ 2>&1& + ./6-logs_client 127.0.0.1 12345 --gras-log=root.thres=error 2>&1 |sed s/6-logs/test/ >> $@ 2>&1 + sleep 1 + echo '$$' >> $@ + echo '$$ ./test_simulator platform.xml test.xml --gras-log=root.thres=error' >> $@ + ./6-logs_simulator gtut-platform.xml 3-args.xml --gras-log=root.thres=error 2>&1 |sed s/6-logs/test/ >> $@ 2>&1 + echo '$$' >> $@ + killall 6-logs_server 6-logs_client 2>/dev/null || true + + +6-logs_client 6-logs_server 6-logs_simulator: _6-logs_client.c _6-logs_server.c _6-logs_simulator.c + make -f 6-logs.mk + +_6-logs_client.c _6-logs_server.c _6-logs_simulator.c: 6-logs.c 3-args.xml + ../../tools/gras/gras_stub_generator 6-logs 3-args.xml >/dev/null + +clean:: + if [ -e 6-logs.mk ] ; then make -f 6-logs.mk clean; fi + rm -f _6-logs_client.c _6-logs_server.c _6-logs_simulator.c 6-logs.trace 6-logs.mk + diff --git a/doc/gtut-main.doc b/doc/gtut-main.doc index acf8959cc9..6ffeaba07f 100644 --- a/doc/gtut-main.doc +++ b/doc/gtut-main.doc @@ -15,6 +15,13 @@ This section constitutes a tutorial to the GRAS programming environment. explains how to install the framework and setup your own projects. Then, an example distributed application is builded incrementaly to show the several aspects of the framework. + - \ref GRAS_tut_tour_install + - \ref GRAS_tut_tour_setup + - \ref GRAS_tut_tour_simpleexchange + - \ref GRAS_tut_tour_args + - \ref GRAS_tut_tour_callbacks + - \ref GRAS_tut_tour_globals + - \ref GRAS_tut_tour_logs \htmlonly \endhtmlonly - \ref GRAS_tut_tour_install @@ -21,6 +22,7 @@ all features available in GRAS. - \ref GRAS_tut_tour_args - \ref GRAS_tut_tour_callbacks - \ref GRAS_tut_tour_globals + - \ref GRAS_tut_tour_logs
-- 2.20.1