Re: [Freeciv-Dev] freelog and LOG_DEBUG
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
David Pfitzner <dwp@xxxxxxxxxxxxxx> writes:
> Or a more sophisticated system where one can turn on or off
> debugs based on __FILE__. Some sort of macro system to avoid
> excessive unnecessary function calls may be appropriate for
> efficiency (like your patch).
How about this:
------------------------------------------------------------------------
1999-05-20 Markus Linnala <maage@xxxxxxxxx>
* server/civserver.c (main): added filespecific debugging
-d 2 - set debug log level to 2 (debug level)
print every debug message
-d 2:file - print debugging only from file `file'
-d 2:file:file2
- print debugging from files `file' and `file2'
-d 2:file,100,200
- print debugging from file `file' if
source code line is >= 100 and <= 200
* common/log.h: new global variables log_files and log_files_cnt
(freelog_debug_check_ok): new function, tell if we need to
print message
(freelog): wrapper macro around real_freelog
* common/log.(c|h> (freelog): change to real_freelog
------------------------------------------------------------------------
I tested the macrosystem agains gcc optimization levels. With
-O3 gcc optimizes out all 'freelog(LOG_DEBUG, message, ...);'
calls if you don't define DEBUG. -O2 does not do so.
This macro system uses GNUC extension to handle ellipsis at
function argument.
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
I think this system is powerful enough (with some general shell
magic) to suit all practical needs.
gcc -DHAVE_CONFIG_H -I. -I/usr/src/freeciv/freeciv/client/gui-gtk -I../..
-I/usr/src/freeciv/freeciv/client/gui-gtk/../include
-I/usr/src/freeciv/freeciv/common -I/usr/X11R6/include -I/usr/lib/glib/include
-I/usr/X11R6/include -DDEBUG -g -Wall -c
/usr/src/freeciv/freeciv/client/gui-gtk/clinet.c
Examples:
civserver -d 2
civserver -d 2:civserver.c
civserver -d 2:civserver.c,700,800
civserver -d 2:`find /usr/src/freeciv/freeciv/ai -name \*.c|tr '\012' ':'|sed
's/:$//'`
From my compilation:
gcc -DHAVE_CONFIG_H -I. -I/usr/src/freeciv/freeciv/client/gui-gtk -I../..
-I/usr/src/freeciv/freeciv/client/gui-gtk/../include
-I/usr/src/freeciv/freeciv/common -I/usr/X11R6/include -I/usr/lib/glib/include
-I/usr/X11R6/include -DDEBUG -g -Wall -c
/usr/src/freeciv/freeciv/client/gui-gtk/clinet.c
If I want to debug the file you have to give:
civserver -d 2:/usr/src/freeciv/freeciv/client/gui-gtk/clinet.c
--
//Markus
--- freeciv-cvs/common/log.c Tue Apr 27 15:17:52 1999
+++ freeciv-maage/common/log.c Thu May 20 05:41:51 1999
@@ -63,7 +63,7 @@
"last message repeated ..." at some later time.
Calls log_callback if non-null, else prints to stderr.
**************************************************************************/
-int freelog(int level, char *message, ...)
+int real_freelog(int level, char *message, ...)
{
static char bufbuf[2][512];
char buf[512];
--- freeciv-cvs/common/log.h Tue Apr 27 15:17:53 1999
+++ freeciv-maage/common/log.h Thu May 20 14:10:40 1999
@@ -14,6 +14,7 @@
#define FC__LOG_H
#include "attribute.h"
+#include <stdarg.h>
#define LOG_FATAL 0
#define LOG_NORMAL 1
@@ -28,7 +29,70 @@
void log_init(char *filename, int initial_level, log_callback_fn callback);
void log_set_level(int level);
-int freelog(int level, char *message, ...)
+int real_freelog(int level, char *message, ...)
fc__attribute((format (printf, 2, 3)));
+
+typedef struct _t_log_files t_log_files;
+
+struct _t_log_files {
+ char *file;
+ int min;
+ int max;
+};
+
+int log_files_cnt;
+t_log_files **log_files;
+
+/* Internal function to check if we need to print debugging information */
+static int freelog_debug_check_ok(const char *file, int line, int level)
+{
+ int i, ok = 1;
+ if(level == LOG_DEBUG)
+ {
+ if (log_files_cnt > 0) ok = 0;
+ for (i = 0; i < log_files_cnt; i++)
+ {
+ if(strcmp(file,log_files[i]->file) == 0
+ && (log_files[i]->max == 0
+ || (log_files[i]->min <= line
+ && log_files[i]->max >= line)))
+ {
+ ok = 1;
+ break;
+ }
+ }
+ }
+ return (ok);
+}
+
+#ifdef ___GNUC__
+#ifdef DEBUG
+#define freelog(level, args...) do { \
+ if (freelog_debug_check_ok(__FILE__, __LINE__, (level))) \
+ real_freelog((level), ##args); \
+} while(0)
+#else
+#define freelog(level, args...) do { \
+ if ((level) != LOG_DEBUG) \
+ real_freelog((level), ##args); \
+} while(0)
+#endif
+#else /* __GNUC__ */
+
+/* Too bad, seems it is not possible to have macro here, so we
+ * lose some functionality in compilers without GNUC extensions. */
+static void freelog (int level, char *message, ...)
+{
+#ifndef DEBUG
+ if ((level) != LOG_DEBUG)
+#endif
+ {
+ va_list args;
+ va_start (args, message);
+ real_freelog(level, message, args);
+ va_end (args);
+ }
+}
+#endif /* __GNUC__ */
#endif
--- freeciv-cvs/server/civserver.c Tue Apr 27 15:17:56 1999
+++ freeciv-maage/server/civserver.c Thu May 20 06:28:52 1999
@@ -81,6 +81,9 @@
extern struct connection connections[];
+extern int log_files_cnt;
+extern t_log_files **log_files;
+
enum server_states server_state;
/* this global is checked deep down the netcode.
@@ -204,13 +207,72 @@
}
}
else if(!strcmp("-d", argv[i]) || !strcmp("--debug", argv[i])) {
- if(++i<argc)
- log_level=atoi(argv[i]);
- else {
- fprintf(stderr, "Error: no debug log level specified.\n");
- h=1;
- break;
- }
+ if(++i<argc) {
+ /*
+ Debug argument can be:
+ 0-2
+ 2:file
+ 2:file,min1,max1
+ 2:file,min1,max1:file2,min2,max2
+ */
+ char *c, *ar;
+ int cnt;
+ cnt = 0;
+ c = argv[i];
+ while((c = index(c, ':')) != NULL) { c++; cnt++; }
+ if (cnt == 0) {
+ log_level=atoi(argv[i]);
+ } else {
+ log_files_cnt = cnt;
+ log_files = (t_log_files **) malloc(log_files_cnt *
sizeof(t_log_files *));
+ /* Clean memory */
+ for (cnt = 0; cnt < log_files_cnt; cnt++)
+ log_files[cnt] = NULL;
+ c = argv[i];
+ if (c[0] == '2' && c[1] == ':') {
+ log_level = 2;
+ ar = strdup(c+2);
+ } else {
+ fprintf(stderr, "Error: no debug log argument
specified.\n");
+ h=1;
+ break;
+ }
+ cnt = 0;
+ while (ar != NULL) {
+ char *pc;
+
+ c = ar;
+ ar = index(ar, ':');
+ if (ar != NULL) {
+ ar[0] = '\0';
+ ar++;
+ }
+ log_files[cnt] = (t_log_files *)
malloc(sizeof(t_log_files));
+ log_files[cnt]->file = c;
+ log_files[cnt]->min = 0;
+ log_files[cnt]->max = 0;
+
+ c = index(c, ',');
+ if (c != NULL) {
+ c[0] = '\0';
+ c++;
+ pc = c;
+ c = index(c, ',');
+ if (c != NULL) {
+ c[0] = '\0';
+ c++;
+ log_files[cnt]->min = atoi(pc);
+ log_files[cnt]->max = atoi(c);
+ }
+ }
+ cnt++;
+ }
+ }
+ } else {
+ fprintf(stderr, "Error: no debug log level specified.\n");
+ h=1;
+ break;
+ }
}
else if(!strcmp("-v", argv[i]) || !strcmp("--version", argv[i])) {
v=1;
@@ -420,17 +482,17 @@
while(server_state==RUN_GAME_STATE) {
force_end_of_sniff=0;
- if(0) freelog(LOG_DEBUG, "Shuffleplayers");
+ freelog(LOG_DEBUG, "Shuffleplayers");
shuffle_players();
- if(0) freelog(LOG_DEBUG, "Aistartturn");
+ freelog(LOG_DEBUG, "Aistartturn");
ai_start_turn();
- if(0) freelog(LOG_DEBUG, "sniffingpackets");
+ freelog(LOG_DEBUG, "sniffingpackets");
while(sniff_packets()==1);
for(i=0;i<game.nplayers;i++)
connection_do_buffer(game.players[i].conn);
- if(0) freelog(LOG_DEBUG, "Autosettlers");
+ freelog(LOG_DEBUG, "Autosettlers");
auto_settlers(); /* moved this after ai_start_turn for efficiency -- Syela
*/
/* moved after sniff_packets for even more efficiency.
What a guy I am. -- Syela */
@@ -438,20 +500,20 @@
/* and now, we must manage our remaining units BEFORE the cities that are
empty get to refresh and defend themselves. How totally stupid. */
ai_start_turn(); /* Misleading name for manage_units -- Syela */
- if(0) freelog(LOG_DEBUG, "Auto-Attack phase");
+ freelog(LOG_DEBUG, "Auto-Attack phase");
auto_attack();
- if(0) freelog(LOG_DEBUG, "Endturn");
+ freelog(LOG_DEBUG, "Endturn");
end_turn();
- if(0) freelog(LOG_DEBUG, "Gamenextyear");
+ freelog(LOG_DEBUG, "Gamenextyear");
game_next_year();
check_spaceship_arrivals();
- if(0) freelog(LOG_DEBUG, "Sendplayerinfo");
+ freelog(LOG_DEBUG, "Sendplayerinfo");
send_player_info(0, 0);
- if(0) freelog(LOG_DEBUG, "Sendgameinfo");
+ freelog(LOG_DEBUG, "Sendgameinfo");
send_game_info(0);
- if(0) freelog(LOG_DEBUG, "Sendyeartoclients");
+ freelog(LOG_DEBUG, "Sendyeartoclients");
send_year_to_clients(game.year);
- if(0) freelog(LOG_DEBUG, "Sendinfotometaserver");
+ freelog(LOG_DEBUG, "Sendinfotometaserver");
send_server_info_to_metaserver(0);
for(i=0;i<game.nplayers;i++)
connection_do_unbuffer(game.players[i].conn);
@@ -716,7 +778,7 @@
*/
struct player *pplayer = shuffled[i];
if (pplayer==NULL) pplayer = &game.players[i];
- if(0) freelog(LOG_DEBUG, "updating player activities for #%d (%s)",
+ freelog(LOG_DEBUG, "updating player activities for #%d (%s)",
i, pplayer->name);
update_player_activities(pplayer);
/* ai unit activity has been moved UP -- Syela */
@@ -729,7 +791,7 @@
update_pollution();
do_apollo_program();
make_history_report();
- if(0) freelog(LOG_DEBUG, "Turn ended.");
+ freelog(LOG_DEBUG, "Turn ended.");
return 1;
}
|
|