Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2004:
[Freeciv-Dev] (PR#8720) Dynamtext
Home

[Freeciv-Dev] (PR#8720) Dynamtext

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#8720) Dynamtext
From: "Raimar Falke" <i-freeciv-lists@xxxxxxxxxxxxx>
Date: Wed, 12 May 2004 06:54:55 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=8720 >


The attached patch extracts the basic functions from client/text.c and
moves them to utility/support.c. There are renamed to dynam(ic)text.

While the reason for client/text.c was mainly concentrating the
functions in one place the main reason for this patch is that you
don't have to guess anylonger how much buffer you need to specify.

The patch also adds a string_join function, removes some redundancy
and adds some consts.

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
 "Your mail could not be delivered to the following Address:
  VTCMC.VTLPR@xxxxxxxxxxxxx        ** Unassigned error message **"

Index: client/options.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/options.c,v
retrieving revision 1.98
diff -u -u -r1.98 options.c
--- client/options.c    22 Apr 2004 02:15:38 -0000      1.98
+++ client/options.c    12 May 2004 13:40:15 -0000
@@ -386,15 +386,13 @@
  OPTION_FILE_NAME define defined in config.h)
  Or NULL if problem.
 *****************************************************************/
-static char *option_file_name(void)
+static const char *option_file_name(void)
 {
-  static char name_buffer[256];
-  char *name;
-
-  name = getenv("FREECIV_OPT");
+  char *name = getenv("FREECIV_OPT");
+  DYNAMTEXT_INIT;
 
   if (name) {
-    sz_strlcpy(name_buffer, name);
+    dynamtext_add("%s", name);
   } else {
 #ifndef OPTION_FILE_NAME
     name = user_home_dir();
@@ -402,14 +400,14 @@
       append_output_window(_("Cannot find your home directory"));
       return NULL;
     }
-    mystrlcpy(name_buffer, name, 231);
-    sz_strlcat(name_buffer, "/.civclientrc");
+    dynamtext_add("%s/.civclientrc", name);
 #else
-    mystrlcpy(name_buffer,OPTION_FILE_NAME,sizeof(name_buffer));
+    dynamtext_add("%s", OPTION_FILE_NAME);
 #endif
   }
-  freelog(LOG_VERBOSE, "settings file is %s", name_buffer);
-  return name_buffer;
+  freelog(LOG_VERBOSE, "settings file is %s", out);
+
+  DYNAMTEXT_RETURN;
 }
   
 /****************************************************************
Index: client/text.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/text.c,v
retrieving revision 1.1
diff -u -u -r1.1 text.c
--- client/text.c       23 Apr 2004 22:58:05 -0000      1.1
+++ client/text.c       12 May 2004 13:40:15 -0000
@@ -31,98 +31,10 @@
 
 #include "text.h"
 
-/*
- * An individual add(_line) string has to fit into GROW_TMP_SIZE. One buffer
- * of GROW_TMP_SIZE size will be allocated for the entire client.
- */
-#define GROW_TMP_SIZE  (1024)
-
-/* 
- * Initial size of the buffer for each function.  It may later be
- * grown as needed.
- */
-#define START_SIZE     10
-
-static void real_add_line(char **buffer, size_t * buffer_size,
-                         const char *format, ...)
-fc__attribute((format(printf, 3, 4)));
-static void real_add(char **buffer, size_t * buffer_size,
-                    const char *format, ...)
-fc__attribute((format(printf, 3, 4)));
-
-#define add_line(...) real_add_line(&out,&out_size, __VA_ARGS__)
-#define add(...) real_add(&out,&out_size, __VA_ARGS__)
-
-#define INIT                   \
-  static char *out = NULL;     \
-  static size_t out_size = 0;  \
-  if (!out) {                  \
-    out_size = START_SIZE;     \
-    out = fc_malloc(out_size); \
-  }                            \
-  out[0] = '\0';
-
-#define RETURN return out;
-
-/****************************************************************************
-  Formats the parameters and appends them. Grows the buffer if
-  required.
-****************************************************************************/
-static void grow_printf(char **buffer, size_t *buffer_size,
-                       const char *format, va_list ap)
-{
-  size_t new_len;
-  static char buf[GROW_TMP_SIZE];
-
-  if (my_vsnprintf(buf, sizeof(buf), format, ap) == -1) {
-    die("Formatted string bigger than %d", sizeof(buf));
-  }
-
-  new_len = strlen(*buffer) + strlen(buf) + 1;
-
-  if (new_len > *buffer_size) {
-    /* It's important that we grow the buffer geometrically, otherwise the
-     * overhead adds up quickly. */
-    size_t new_size = MAX(new_len, *buffer_size * 2);
-
-    freelog(LOG_VERBOSE, "expand from %d to %d to add '%s'",
-           *buffer_size, new_size, buf);
-
-    *buffer_size = new_size;
-    *buffer = fc_realloc(*buffer, *buffer_size);
-  }
-  mystrlcat(*buffer, buf, *buffer_size);
-}
-
-/****************************************************************************
-  Add a full line of text to the buffer.
-****************************************************************************/
-static void real_add_line(char **buffer, size_t * buffer_size,
-                         const char *format, ...)
-{
-  va_list args;
-
-  if ((*buffer)[0] != '\0') {
-    real_add(buffer, buffer_size, "%s", "\n");
-  }
-
-  va_start(args, format);
-  grow_printf(buffer, buffer_size, format, args);
-  va_end(args);
-}
-
-/****************************************************************************
-  Add the text to the buffer.
-****************************************************************************/
-static void real_add(char **buffer, size_t * buffer_size, const char *format,
-                    ...)
-{
-  va_list args;
-
-  va_start(args, format);
-  grow_printf(buffer, buffer_size, format, args);
-  va_end(args);
-}
+#define add_line dynamtext_add_line
+#define add dynamtext_add
+#define INIT DYNAMTEXT_INIT
+#define RETURN DYNAMTEXT_RETURN
 
 /****************************************************************************
   Text to popup on a middle-click in the mapview.
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.208
diff -u -u -r1.208 city.c
--- common/city.c       6 May 2004 21:28:03 -0000       1.208
+++ common/city.c       12 May 2004 13:40:17 -0000
@@ -250,8 +250,8 @@
 **************************************************************************/
 const char *get_impr_name_ex(struct city *pcity, Impr_Type_id id)
 {
-  static char buffer[256];
   const char *state = NULL;
+  DYNAMTEXT_INIT;
 
   if (pcity) {
     switch (pcity->improvements[id]) {
@@ -268,12 +268,11 @@
   }
   
   if (state) {
-    my_snprintf(buffer, sizeof(buffer), "%s(%s)",
-               get_improvement_name(id), state); 
-    return buffer;
+    dynamtext_add("%s(%s)",get_improvement_name(id), state); 
   } else {
-    return get_improvement_name(id);
+    dynamtext_add("%s",get_improvement_name(id));
   }
+  DYNAMTEXT_RETURN;
 }
 
 /**************************************************************************
Index: common/connection.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/connection.c,v
retrieving revision 1.38
diff -u -u -r1.38 connection.c
--- common/connection.c 5 May 2004 20:39:16 -0000       1.38
+++ common/connection.c 12 May 2004 13:40:17 -0000
@@ -472,28 +472,25 @@
 **************************************************************************/
 const char *conn_description(const struct connection *pconn)
 {
-  static char buffer[MAX_LEN_NAME*2 + MAX_LEN_ADDR + 128];
-
-  buffer[0] = '\0';
+  DYNAMTEXT_INIT;
 
   if (*pconn->username != '\0') {
-    my_snprintf(buffer, sizeof(buffer), _("%s from %s"),
-               pconn->username, pconn->addr); 
+    dynamtext_add(_("%s from %s"), pconn->username, pconn->addr);
   } else {
-    sz_strlcpy(buffer, "server");
+    dynamtext_add("server");
   }
   if (!pconn->established) {
-    sz_strlcat(buffer, _(" (connection incomplete)"));
-    return buffer;
-  }
-  if (pconn->player) {
-    cat_snprintf(buffer, sizeof(buffer), _(" (player %s)"),
-                pconn->player->name);
-  }
-  if (pconn->observer) {
-    sz_strlcat(buffer, _(" (observer)"));
+    dynamtext_add("%s", _(" (connection incomplete)"));
+  } else {
+    if (pconn->player) {
+      dynamtext_add(_(" (player %s)"), pconn->player->name);
+    }
+    if (pconn->observer) {
+      dynamtext_add("%s", _(" (observer)"));
+    }
   }
-  return buffer;
+
+  DYNAMTEXT_RETURN;
 }
 
 /**************************************************************************
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.165
diff -u -u -r1.165 map.c
--- common/map.c        20 Apr 2004 20:10:37 -0000      1.165
+++ common/map.c        12 May 2004 13:40:18 -0000
@@ -87,63 +87,40 @@
 ***************************************************************/
 const char *map_get_tile_info_text(int x, int y)
 {
-  static char s[64];
-  struct tile *ptile=map_get_tile(x, y);
-  bool first;
+  struct tile *ptile = map_get_tile(x, y);
+  const char *arr[2];
+  int n;
+  DYNAMTEXT_INIT;
+
+  dynamtext_add("%s", tile_types[ptile->terrain].terrain_name);
 
-  sz_strlcpy(s, tile_types[ptile->terrain].terrain_name);
   if (tile_has_special(ptile, S_RIVER)) {
-    sz_strlcat(s, "/");
-    sz_strlcat(s, get_special_name(S_RIVER));
+    dynamtext_add("/%s", get_special_name(S_RIVER));
   }
 
-  first = TRUE;
+  n = 0;
   if (tile_has_special(ptile, S_SPECIAL_1)) {
-    if (first) {
-      first = FALSE;
-      sz_strlcat(s, " (");
-    } else {
-      sz_strlcat(s, "/");
-    }
-    sz_strlcat(s, tile_types[ptile->terrain].special_1_name);
+    arr[n] = tile_types[ptile->terrain].special_1_name;
+    n++;
   }
   if (tile_has_special(ptile, S_SPECIAL_2)) {
-    if (first) {
-      first = FALSE;
-      sz_strlcat(s, " (");
-    } else {
-      sz_strlcat(s, "/");
-    }
-    sz_strlcat(s, tile_types[ptile->terrain].special_2_name);
-  }
-  if (!first) {
-    sz_strlcat(s, ")");
+    arr[n] = tile_types[ptile->terrain].special_2_name;
+    n++;
   }
+  dynamtext_add("%s", string_join(n, arr, "/", "/", " (", ")"));
 
-  first = TRUE;
+  n = 0;
   if (tile_has_special(ptile, S_POLLUTION)) {
-    if (first) {
-      first = FALSE;
-      sz_strlcat(s, " [");
-    } else {
-      sz_strlcat(s, "/");
-    }
-    sz_strlcat(s, get_special_name(S_POLLUTION));
+    arr[n] = get_special_name(S_POLLUTION);
+    n++;
   }
   if (tile_has_special(ptile, S_FALLOUT)) {
-    if (first) {
-      first = FALSE;
-      sz_strlcat(s, " [");
-    } else {
-      sz_strlcat(s, "/");
-    }
-    sz_strlcat(s, get_special_name(S_FALLOUT));
-  }
-  if (!first) {
-    sz_strlcat(s, "]");
+    arr[n] = get_special_name(S_FALLOUT);
+    n++;
   }
+  dynamtext_add("%s", string_join(n, arr, "/", "/", " [", "]"));
 
-  return s;
+  DYNAMTEXT_RETURN;
 }
 
 /***************************************************************
@@ -151,13 +128,12 @@
 ***************************************************************/
 const char *map_get_tile_fpt_text(int x, int y)
 {
-  static char s[64];
-  
-  my_snprintf(s, sizeof(s), "%d/%d/%d",
-             get_food_tile(x, y),
-             get_shields_tile(x, y),
-             get_trade_tile(x, y));
-  return s;
+  DYNAMTEXT_INIT;
+
+  dynamtext_add("%d/%d/%d", get_food_tile(x, y), get_shields_tile(x, y),
+               get_trade_tile(x, y));
+
+  DYNAMTEXT_RETURN;
 }
 
 /***************************************************************
@@ -476,37 +452,36 @@
 ***************************************************************/
 const char *map_get_infrastructure_text(enum tile_special_type spe)
 {
-  static char s[64];
-  char *p;
-  
-  s[0] = '\0';
+  const char *arr[5];
+  int n = 0;
 
   /* Since railroad requires road, Road/Railroad is redundant */
-  if (contains_special(spe, S_RAILROAD))
-    cat_snprintf(s, sizeof(s), "%s/", _("Railroad"));
-  else if (contains_special(spe, S_ROAD))
-    cat_snprintf(s, sizeof(s), "%s/", _("Road"));
+  if (contains_special(spe, S_RAILROAD)) {
+    arr[n++] = _("Railroad");
+  } else if (contains_special(spe, S_ROAD)) {
+    arr[n++] = _("Road");
+  }
 
   /* Likewise for farmland on irrigation */
-  if (contains_special(spe, S_FARMLAND))
-    cat_snprintf(s, sizeof(s), "%s/", _("Farmland"));
-  else if (contains_special(spe, S_IRRIGATION))
-    cat_snprintf(s, sizeof(s), "%s/", _("Irrigation"));
-
-  if (contains_special(spe, S_MINE))
-    cat_snprintf(s, sizeof(s), "%s/", _("Mine"));
+  if (contains_special(spe, S_FARMLAND)) {
+    arr[n++] = _("Farmland");
+  } else if (contains_special(spe, S_IRRIGATION)) {
+    arr[n++] = _("Irrigation");
+  }
 
-  if (contains_special(spe, S_FORTRESS))
-    cat_snprintf(s, sizeof(s), "%s/", _("Fortress"));
+  if (contains_special(spe, S_MINE)) {
+    arr[n++] = _("Mine");
+  }
 
-  if (contains_special(spe, S_AIRBASE))
-    cat_snprintf(s, sizeof(s), "%s/", _("Airbase"));
+  if (contains_special(spe, S_FORTRESS)) {
+    arr[n++] = _("Fortress");
+  }
 
-  p = s + strlen(s) - 1;
-  if (*p == '/')
-    *p = '\0';
+  if (contains_special(spe, S_AIRBASE)) {
+    arr[n++] = _("Airbase");
+  }
 
-  return s;
+  return string_join(n, arr, "/", "/", NULL, NULL);
 }
 
 /****************************************************************************
Index: common/tech.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tech.c,v
retrieving revision 1.70
diff -u -u -r1.70 tech.c
--- common/tech.c       31 Jan 2004 17:52:41 -0000      1.70
+++ common/tech.c       12 May 2004 13:40:22 -0000
@@ -545,18 +545,18 @@
 **************************************************************************/
 const char *get_tech_name(struct player *pplayer, Tech_Type_id tech)
 {
-  static char buffer[200];
+  DYNAMTEXT_INIT;
 
   if (tech == A_NOINFO) {
-    my_snprintf(buffer, sizeof(buffer), _("(Unknown)"));
+    dynamtext_add("%s", _("(Unknown)"));
   } else if (!is_future_tech(tech)) {
     assert(tech_exists(tech));
-    my_snprintf(buffer, sizeof(buffer), "%s", advances[tech].name);
+    dynamtext_add("%s", advances[tech].name);
   } else {
-    my_snprintf(buffer, sizeof(buffer), _("Future Tech. %d"),
-               pplayer->future_tech + 1);
+    dynamtext_add(_("Future Tech. %d"), pplayer->future_tech + 1);
   }
-  return buffer;
+
+  DYNAMTEXT_RETURN;
 }
 
 /**************************************************************************
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.209
diff -u -u -r1.209 unit.c
--- common/unit.c       6 May 2004 21:28:03 -0000       1.209
+++ common/unit.c       12 May 2004 13:40:23 -0000
@@ -1024,77 +1024,59 @@
 **************************************************************************/
 const char *unit_activity_text(struct unit *punit)
 {
-  static char text[64];
-  const char *moves_str;
-   
-  switch(punit->activity) {
-   case ACTIVITY_IDLE:
-     moves_str = _("Moves");
-     if (is_air_unit(punit) && unit_type(punit)->fuel > 0) {
-       int rate,f;
-       rate=unit_type(punit)->move_rate/SINGLE_MOVE;
-       f=((punit->fuel)-1);
-      if ((punit->moves_left % SINGLE_MOVE) != 0) {
-        if(punit->moves_left/SINGLE_MOVE>0) {
-          my_snprintf(text, sizeof(text), "%s: (%d)%d %d/%d", moves_str,
-                      ((rate*f)+(punit->moves_left/SINGLE_MOVE)),
-                      punit->moves_left/SINGLE_MOVE, 
punit->moves_left%SINGLE_MOVE,
-                      SINGLE_MOVE);
-        } else {
-          my_snprintf(text, sizeof(text), "%s: (%d)%d/%d", moves_str,
-                      ((rate*f)+(punit->moves_left/SINGLE_MOVE)),
-                      punit->moves_left%SINGLE_MOVE, SINGLE_MOVE);
-        }
-       } else {
-        my_snprintf(text, sizeof(text), "%s: (%d)%d", moves_str,
-                    rate*f+punit->moves_left/SINGLE_MOVE,
-                    punit->moves_left/SINGLE_MOVE);
-       }
-     } else {
-      if ((punit->moves_left % SINGLE_MOVE) != 0) {
-        if(punit->moves_left/SINGLE_MOVE>0) {
-          my_snprintf(text, sizeof(text), "%s: %d %d/%d", moves_str,
-                      punit->moves_left/SINGLE_MOVE, 
punit->moves_left%SINGLE_MOVE,
-                      SINGLE_MOVE);
-        } else {
-          my_snprintf(text, sizeof(text),
-                      "%s: %d/%d", moves_str, punit->moves_left%SINGLE_MOVE,
-                      SINGLE_MOVE);
-        }
-       } else {
-        my_snprintf(text, sizeof(text),
-                    "%s: %d", moves_str, punit->moves_left/SINGLE_MOVE);
-       }
-     }
-     return text;
-   case ACTIVITY_POLLUTION:
-   case ACTIVITY_FALLOUT:
-   case ACTIVITY_ROAD:
-   case ACTIVITY_RAILROAD:
-   case ACTIVITY_MINE: 
-   case ACTIVITY_IRRIGATE:
-   case ACTIVITY_TRANSFORM:
-   case ACTIVITY_FORTIFYING:
-   case ACTIVITY_FORTIFIED:
-   case ACTIVITY_AIRBASE:
-   case ACTIVITY_FORTRESS:
-   case ACTIVITY_SENTRY:
-   case ACTIVITY_GOTO:
-   case ACTIVITY_EXPLORE:
-     return get_activity_text (punit->activity);
-   case ACTIVITY_PILLAGE:
-     if(punit->activity_target == S_NO_SPECIAL) {
-       return get_activity_text (punit->activity);
-     } else {
-       my_snprintf(text, sizeof(text), "%s: %s",
-                  get_activity_text (punit->activity),
-                  map_get_infrastructure_text(punit->activity_target));
-       return (text);
-     }
-   default:
+  DYNAMTEXT_INIT;
+
+  switch (punit->activity) {
+  case ACTIVITY_IDLE:
+    dynamtext_add("%s: ", _("Moves"));
+
+    if (is_air_unit(punit) && unit_type(punit)->fuel > 0) {
+      int rate = unit_type(punit)->move_rate / SINGLE_MOVE;
+      int f = punit->fuel - 1;
+
+      dynamtext_add("(%d)", rate * f + punit->moves_left / SINGLE_MOVE);
+    }
+
+    if ((punit->moves_left % SINGLE_MOVE) != 0) {
+      if (punit->moves_left / SINGLE_MOVE > 0) {
+       dynamtext_add("%d %d/%d",
+                     punit->moves_left / SINGLE_MOVE,
+                     punit->moves_left % SINGLE_MOVE, SINGLE_MOVE);
+      } else {
+       dynamtext_add("%d/%d", punit->moves_left % SINGLE_MOVE, SINGLE_MOVE);
+      }
+    } else {
+      dynamtext_add("%d", punit->moves_left / SINGLE_MOVE);
+    }
+
+    break;
+  case ACTIVITY_POLLUTION:
+  case ACTIVITY_FALLOUT:
+  case ACTIVITY_ROAD:
+  case ACTIVITY_RAILROAD:
+  case ACTIVITY_MINE:
+  case ACTIVITY_IRRIGATE:
+  case ACTIVITY_TRANSFORM:
+  case ACTIVITY_FORTIFYING:
+  case ACTIVITY_FORTIFIED:
+  case ACTIVITY_AIRBASE:
+  case ACTIVITY_FORTRESS:
+  case ACTIVITY_SENTRY:
+  case ACTIVITY_GOTO:
+  case ACTIVITY_EXPLORE:
+    dynamtext_add("%s", get_activity_text(punit->activity));
+    break;
+  case ACTIVITY_PILLAGE:
+    dynamtext_add("%s", get_activity_text(punit->activity));
+    if (punit->activity_target != S_NO_SPECIAL) {
+      dynamtext_add(": %s",
+                   map_get_infrastructure_text(punit->activity_target));
+    }
+    break;
+  default:
     die("Unknown unit activity %d in unit_activity_text()", punit->activity);
   }
-  return NULL;
+  DYNAMTEXT_RETURN;
 }
 
 /**************************************************************************
Index: common/unittype.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unittype.c,v
retrieving revision 1.33
diff -u -u -r1.33 unittype.c
--- common/unittype.c   6 May 2004 21:28:03 -0000       1.33
+++ common/unittype.c   12 May 2004 13:40:23 -0000
@@ -241,20 +241,19 @@
 **************************************************************************/
 const char *get_unit_name(Unit_Type_id id)
 {
-  struct unit_type *ptype;
-  static char buffer[256];
-  ptype =get_unit_type(id);
+  struct unit_type *ptype = get_unit_type(id);
+  DYNAMTEXT_INIT;
+
   if (ptype->fuel > 0) {
-    my_snprintf(buffer, sizeof(buffer),
-               "%s [%d/%d/%d(%d)]", ptype->name, ptype->attack_strength,
-               ptype->defense_strength,
-               ptype->move_rate/3,(ptype->move_rate/3)*ptype->fuel);
+    dynamtext_add("%s [%d/%d/%d(%d)]", ptype->name, ptype->attack_strength,
+                 ptype->defense_strength,
+                 ptype->move_rate / 3,
+                 (ptype->move_rate / 3) * ptype->fuel);
   } else {
-    my_snprintf(buffer, sizeof(buffer),
-               "%s [%d/%d/%d]", ptype->name, ptype->attack_strength,
-               ptype->defense_strength, ptype->move_rate/3);
+    dynamtext_add("%s [%d/%d/%d]", ptype->name, ptype->attack_strength,
+                 ptype->defense_strength, ptype->move_rate / 3);
   }
-  return buffer;
+  DYNAMTEXT_RETURN;
 }
 
 /**************************************************************************
Index: common/version.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/version.c,v
retrieving revision 1.7
diff -u -u -r1.7 version.c
--- common/version.c    2 May 2004 11:42:23 -0000       1.7
+++ common/version.c    12 May 2004 13:40:23 -0000
@@ -16,6 +16,7 @@
 #endif
 
 #include "fcintl.h"
+#include "mem.h"
 #include "shared.h"
 #include "support.h"
 
@@ -27,17 +28,16 @@
 ***********************************************************************/
 const char *freeciv_name_version(void)
 {
-  static char msgbuf[128];
+  DYNAMTEXT_INIT;
 
 #if IS_BETA_VERSION
-  my_snprintf(msgbuf, sizeof (msgbuf), _("Freeciv version %s %s"),
-              VERSION_STRING, _("(beta version)"));
+  dynamtext_add(_("Freeciv version %s %s"), VERSION_STRING,
+               _("(beta version)"));
 #else
-  my_snprintf(msgbuf, sizeof (msgbuf), _("Freeciv version %s"),
-              VERSION_STRING);
+  dynamtext_add(_("Freeciv version %s"), VERSION_STRING);
 #endif
 
-  return msgbuf;
+  DYNAMTEXT_RETURN;
 }
 
 /**********************************************************************
@@ -59,7 +59,6 @@
 const char *beta_message(void)
 {
 #if IS_BETA_VERSION
-  static char msgbuf[128];
   static const char *month[] =
   {
     NULL,
@@ -76,16 +75,16 @@
     N_("November"),
     N_("December")
   };
-  my_snprintf (msgbuf, sizeof (msgbuf),
-              _("THIS IS A BETA VERSION\n"
-                "Freeciv %s will be released in\n"
-                "%s, at %s"), /* No full stop here since it would be
-                                 immediately following a URL, which
-                                 would only cause confusion. */
-              NEXT_STABLE_VERSION,
-              _(NEXT_RELEASE_MONTH),
-              WEBSITE_URL);
-  return msgbuf;
+  DYNAMTEXT_INIT;
+
+  dynamtext_add(_("THIS IS A BETA VERSION\n" 
+                 "Freeciv %s will be released in\n" 
+                 "%s, at %s"), 
+               /* No full stop here since it would be immediately
+                  following a URL, which would only cause
+                  confusion. */
+               NEXT_STABLE_VERSION, _(NEXT_RELEASE_MONTH), WEBSITE_URL);
+  DYNAMTEXT_RETURN;
 #else
   return NULL;
 #endif
Index: server/meta.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/meta.c,v
retrieving revision 1.59
diff -u -u -r1.59 meta.c
--- server/meta.c       25 Jan 2004 13:55:14 -0000      1.59
+++ server/meta.c       12 May 2004 13:40:24 -0000
@@ -109,18 +109,17 @@
 /*************************************************************************
 ...
 *************************************************************************/
-char *meta_addr_port(void)
+const char *meta_addr_port(void)
 {
-  static char retstr[300];
+  DYNAMTEXT_INIT;
 
   if (srvarg.metaserver_port == DEFAULT_META_SERVER_PORT) {
-    sz_strlcpy(retstr, srvarg.metaserver_addr);
+    dynamtext_add("%s",srvarg.metaserver_addr);
   } else {
-    my_snprintf(retstr, sizeof(retstr),
-               "%s:%d", srvarg.metaserver_addr, srvarg.metaserver_port);
+    dynamtext_add("%s:%d", srvarg.metaserver_addr, srvarg.metaserver_port);
   }
 
-  return retstr;
+  DYNAMTEXT_RETURN;
 }
 
 /*************************************************************************
Index: server/meta.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/meta.h,v
retrieving revision 1.24
diff -u -u -r1.24 meta.h
--- server/meta.h       7 Nov 2002 16:04:54 -0000       1.24
+++ server/meta.h       12 May 2004 13:40:24 -0000
@@ -29,7 +29,7 @@
 const char *default_meta_server_info_string(void);
 
 void meta_addr_split(void);
-char *meta_addr_port(void);
+const char *meta_addr_port(void);
 
 void server_close_udp(void);
 void server_open_udp(void);
Index: server/report.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/report.c,v
retrieving revision 1.49
diff -u -u -r1.49 report.c
--- server/report.c     28 Nov 2003 17:37:22 -0000      1.49
+++ server/report.c     12 May 2004 13:40:25 -0000
@@ -532,13 +532,11 @@
 **************************************************************************/
 static const char *value_units(int val, const char *uni)
 {
-  static char buf[64];
+  DYNAMTEXT_INIT;
 
-  if (my_snprintf(buf, sizeof(buf), "%s%s", int_to_text(val), uni) == -1) {
-    die("String truncated in value_units()!");
-  }
+  dynamtext_add("%s%s", int_to_text(val), uni);
 
-  return buf;
+  DYNAMTEXT_RETURN;
 }
 
 /**************************************************************************
@@ -580,22 +578,22 @@
 **************************************************************************/
 static const char *number_to_ordinal_string(int num)
 {
-  static char buf[16];
-  char fmt[] = "(%d%s)";
+  const char fmt[] = "(%d%s)";
+  DYNAMTEXT_INIT;
 
   assert(num > 0);
 
   if ((num % 10) == 1 && num != 11) {
-    my_snprintf(buf, sizeof(buf), fmt, num, _("st"));
+    dynamtext_add(fmt, num, _("st"));
   } else if ((num % 10) == 2 && num != 12) {
-    my_snprintf(buf, sizeof(buf), fmt, num, _("nd"));
+    dynamtext_add(fmt, num, _("nd"));
   } else if ((num % 10) == 3 && num != 13) {
-    my_snprintf(buf, sizeof(buf), fmt, num, _("rd"));
+    dynamtext_add(fmt, num, _("rd"));
   } else {
-    my_snprintf(buf, sizeof(buf), fmt, num, _("th"));
+    dynamtext_add(fmt, num, _("th"));
   }
 
-  return buf;
+  DYNAMTEXT_RETURN;
 }
 
 /**************************************************************************
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.292
diff -u -u -r1.292 unittools.c
--- server/unittools.c  10 May 2004 22:29:20 -0000      1.292
+++ server/unittools.c  12 May 2004 13:40:27 -0000
@@ -984,39 +984,36 @@
   not "in" the city (since the attacker never made it in).
   Don't call this function directly; use the wrappers below.
 **************************************************************************/
-static char *get_location_str(struct player *pplayer, int x, int y, bool 
use_at)
+static const char *get_location_str(struct player *pplayer, int x, int y,
+                                   bool use_at)
 {
-  static char buffer[MAX_LEN_NAME+64];
-  struct city *incity, *nearcity;
+  struct city *incity = map_get_city(x, y);
+  DYNAMTEXT_INIT;
 
-  incity = map_get_city(x, y);
   if (incity) {
     if (use_at) {
-      my_snprintf(buffer, sizeof(buffer), _(" at %s"), incity->name);
+      dynamtext_add(_(" at %s"), incity->name);
     } else {
-      my_snprintf(buffer, sizeof(buffer), _(" in %s"), incity->name);
+      dynamtext_add(_(" in %s"), incity->name);
     }
   } else {
-    nearcity = dist_nearest_city(pplayer, x, y, FALSE, FALSE);
+    struct city *nearcity = dist_nearest_city(pplayer, x, y, FALSE, FALSE);
+
     if (nearcity) {
       if (is_tiles_adjacent(x, y, nearcity->x, nearcity->y)) {
-       my_snprintf(buffer, sizeof(buffer),
-                  _(" outside %s"), nearcity->name);
+       dynamtext_add(_(" outside %s"), nearcity->name);
       } else {
-       my_snprintf(buffer, sizeof(buffer),
-                   _(" near %s"), nearcity->name);
+       dynamtext_add(_(" near %s"), nearcity->name);
       }
-    } else {
-      buffer[0] = '\0';
     }
   }
-  return buffer;
+  DYNAMTEXT_RETURN;
 }
 
 /**************************************************************************
   See get_location_str() above.
 **************************************************************************/
-char *get_location_str_in(struct player *pplayer, int x, int y)
+const char *get_location_str_in(struct player *pplayer, int x, int y)
 {
   return get_location_str(pplayer, x, y, FALSE);
 }
@@ -1024,7 +1021,7 @@
 /**************************************************************************
   See get_location_str() above.
 **************************************************************************/
-char *get_location_str_at(struct player *pplayer, int x, int y)
+const char *get_location_str_at(struct player *pplayer, int x, int y)
 {
   return get_location_str(pplayer, x, y, TRUE);
 }
@@ -1713,7 +1710,7 @@
 {
   struct player *pplayer   = unit_owner(punit);
   struct player *destroyer = unit_owner(pkiller);
-  char *loc_str = get_location_str_in(pplayer, punit->x, punit->y);
+  const char *loc_str = get_location_str_in(pplayer, punit->x, punit->y);
   int num_killed[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
   int ransom, unitcount = 0;
   
Index: server/unittools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.h,v
retrieving revision 1.68
diff -u -u -r1.68 unittools.h
--- server/unittools.h  14 Apr 2004 11:19:45 -0000      1.68
+++ server/unittools.h  12 May 2004 13:40:27 -0000
@@ -37,8 +37,8 @@
 int get_settler_speed(struct unit *punit);
 
 /* various */
-char *get_location_str_in(struct player *pplayer, int x, int y);
-char *get_location_str_at(struct player *pplayer, int x, int y);
+const char *get_location_str_in(struct player *pplayer, int x, int y);
+const char *get_location_str_at(struct player *pplayer, int x, int y);
 enum goto_move_restriction get_activity_move_restriction(enum unit_activity 
activity);
 void make_partisans(struct city *pcity);
 bool enemies_at(struct unit *punit, int x, int y);
Index: utility/shared.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/shared.c,v
retrieving revision 1.110
diff -u -u -r1.110 shared.c
--- utility/shared.c    2 May 2004 11:42:24 -0000       1.110
+++ utility/shared.c    12 May 2004 13:40:27 -0000
@@ -66,6 +66,13 @@
                           "~/.freeciv"
 #endif
 
+/*
+ * An individual add(_line) string has to fit into
+ * DYNAMTEXT_GROW_TMP_SIZE. One buffer of DYNAMTEXT_GROW_TMP_SIZE size
+ * will be allocated for the entire client.
+ */
+#define DYNAMTEXT_GROW_TMP_SIZE        (1024)
+
 static char *grouping = NULL;
 static char *grouping_sep = NULL;
 static size_t grouping_sep_len = 0;
@@ -275,6 +282,38 @@
 }
 
 /***************************************************************
+  Joins the n strings. Between the last and the second last end_deli
+  is placed else normal_deli.
+
+  If start is given (!=NULL) and n>0 the result is prefixed with
+  start. If end is given and n>0 end is appended to the result.
+***************************************************************/
+const char *string_join(int n, const char **strings,
+                       const char *normal_deli, const char *end_deli,
+                       const char *start, const char *end)
+{
+  int i;
+  DYNAMTEXT_INIT;
+
+  if (n > 0 && start) {
+    dynamtext_add("%s", start);
+  }
+  for (i = 0; i < n; i++) {
+    dynamtext_add("%s", strings[i]);
+
+    if (i == n - 2) {
+      dynamtext_add("%s", end_deli);
+    } else if (i < n - 1) {
+      dynamtext_add("%s", normal_deli);
+    }
+  }
+  if (n > 0 && end) {
+    dynamtext_add("%s", end);
+  }
+  DYNAMTEXT_RETURN;
+}
+
+/***************************************************************
   Returns a statically allocated string containing a nicely-formatted
   version of the given number according to the user's locale.  (Only
   works for numbers >= zero.) The actually number used for the
@@ -410,12 +449,14 @@
 ***************************************************************/
 const char *textyear(int year)
 {
-  static char y[32];
-  if (year<0) 
-    my_snprintf(y, sizeof(y), _("%d BC"), -year);
-  else
-    my_snprintf(y, sizeof(y), _("%d AD"), year);
-  return y;
+  DYNAMTEXT_INIT;
+
+  if (year < 0) {
+    dynamtext_add(_("%d BC"), -year);
+  } else {
+    dynamtext_add(_("%d AD"), year);
+  }
+  DYNAMTEXT_RETURN;
 }
 
 /**************************************************************************
@@ -1317,3 +1358,64 @@
   }
   return group;
 }
+
+/****************************************************************************
+  Formats the parameters and appends them. Grows the buffer if
+  required.
+****************************************************************************/
+static void grow_printf(char **buffer, size_t *buffer_size,
+                       const char *format, va_list ap)
+{
+  size_t new_len;
+  static char buf[DYNAMTEXT_GROW_TMP_SIZE];
+
+  if (my_vsnprintf(buf, sizeof(buf), format, ap) == -1) {
+    die("Formatted string bigger than %d", sizeof(buf));
+  }
+
+  new_len = strlen(*buffer) + strlen(buf) + 1;
+
+  if (new_len > *buffer_size) {
+    /* It's important that we grow the buffer geometrically, otherwise the
+     * overhead adds up quickly. */
+    size_t new_size = MAX(new_len, *buffer_size * 2);
+
+    freelog(LOG_VERBOSE, "expand from %d to %d to add '%s'",
+           *buffer_size, new_size, buf);
+
+    *buffer_size = new_size;
+    *buffer = fc_realloc(*buffer, *buffer_size);
+  }
+  mystrlcat(*buffer, buf, *buffer_size);
+}
+
+/****************************************************************************
+  Add a full line of text to the buffer.  
+****************************************************************************/
+void real_dynamtext_add_line(char **buffer, size_t * buffer_size,
+                            const char *format, ...)
+{
+  va_list args;
+
+  if ((*buffer)[0] != '\0') {
+    real_dynamtext_add(buffer, buffer_size, "%s", "\n");
+  }
+
+  va_start(args, format);
+  grow_printf(buffer, buffer_size, format, args);
+  va_end(args);
+}
+
+/****************************************************************************
+  Add the text to the buffer.
+****************************************************************************/
+void real_dynamtext_add(char **buffer, size_t * buffer_size,
+                       const char *format, ...)
+{
+  va_list args;
+
+  va_start(args, format);
+  grow_printf(buffer, buffer_size, format, args);
+  va_end(args);
+}
+
Index: utility/shared.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/shared.h,v
retrieving revision 1.125
diff -u -u -r1.125 shared.h
--- utility/shared.h    2 May 2004 11:42:24 -0000       1.125
+++ utility/shared.h    12 May 2004 13:40:28 -0000
@@ -170,6 +170,10 @@
 bool is_option(const char *option_name,char *option);
 int get_tokens(const char *str, char **tokens, size_t num_tokens,
               const char *delimiterset);
+const char *string_join(int n, const char **strings,
+                       const char *normal_deli, const char *end_deli,
+                       const char *start, const char *end);
+
 const char *int_to_text(int nr);
 const char *population_to_text(int thousand_citizen);
 
@@ -235,4 +239,25 @@
 
 char *get_multicast_group(void);
 
+void real_dynamtext_add_line(char **buffer, size_t * buffer_size,
+                            const char *format, ...)
+fc__attribute((format(printf, 3, 4)));
+void real_dynamtext_add(char **buffer, size_t * buffer_size,
+                       const char *format, ...)
+fc__attribute((format(printf, 3, 4)));
+
+#define dynamtext_add_line(...)        \
+  real_dynamtext_add_line(&out, &out_size, __VA_ARGS__)
+#define dynamtext_add(...)     \
+  real_dynamtext_add(&out, &out_size, __VA_ARGS__)
+#define DYNAMTEXT_INIT         \
+  static char *out = NULL;     \
+  static size_t out_size = 0;  \
+  if (!out) {                  \
+    out_size = 4;      \
+    out = fc_malloc(out_size); \
+  }                            \
+  out[0] = '\0';
+#define DYNAMTEXT_RETURN       return out;
+
 #endif  /* FC__SHARED_H */

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#8720) Dynamtext, Raimar Falke <=