tPad drug names by character, not byte - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit c3e83bb7dab692ce7febbe46d21261c4a664f6a7
 (DIR) parent 0f3258aeb3b48e9d859770c2ba81750fc4460010
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Sun, 29 Nov 2020 22:58:32 -0800
       
       Pad drug names by character, not byte
       
       If we're in a UTF-8 locale with accented characters,
       strings might be longer in bytes than in characters;
       tthis results in drug names not lining up in the curses
       "drugs here" output. Pad using the length in characters
       instead to fix this.
       
       Diffstat:
         M src/curses_client/curses_client.c   |      25 +++++++++++++++++++++++--
         M src/dopewars.c                      |       3 +++
         M src/dopewars.h                      |       1 +
         M src/winmain.c                       |       1 +
       
       4 files changed, 28 insertions(+), 2 deletions(-)
       ---
 (DIR) diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_client.c
       t@@ -2241,6 +2241,25 @@ char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly,
          return ReturnString;
        }
        
       +/* Return a blank string long enough to pad `name` out to `pad_len`.
       +   This works with characters, not bytes, if in a UTF-8 locale */
       +static char *pad_name(const char *name, guint pad_len)
       +{
       +  /* 40 character blank string (must be longer than max value of pad_len) */
       +  static char *pad = "                                        ";
       +  int slen;
       +  if (LocaleIsUTF8) {
       +    slen = g_utf8_strlen(name, -1);
       +  } else {
       +    slen = strlen(name);
       +  }
       +  if (slen > pad_len || slen > 40) {
       +    return "";
       +  } else {
       +    return pad + 40 - pad_len + slen;
       +  }
       +}
       +
        static void DisplayDrugsHere(Player *Play)
        {
          int NumDrugsHere, i, c;
       t@@ -2265,8 +2284,9 @@ static void DisplayDrugsHere(Player *Play)
               c++, i = GetNextDrugIndex(i, Play)) {
            /* List of individual drug names for selection (%tde="Opium" etc.
               by default) */
       -    text = dpg_strdup_printf( _("%c. %-10tde %8P"), 'A' + c,
       -                             Drug[i].Name, Play->Drugs[i].Price);
       +    text = dpg_strdup_printf( _("%c. %tde%s %8P"), 'A' + c,
       +                             Drug[i].Name, pad_name(Drug[i].Name, 10),
       +                             Play->Drugs[i].Price);
            names = g_slist_append(names, text);
          }
          display_select_list(names);
       t@@ -2654,6 +2674,7 @@ void CursesLoop(struct CMDLINE *cmdline)
          /* On Windows, force UTF-8 rather than the non-Unicode codepage */
          bind_textdomain_codeset(PACKAGE, "UTF-8");
          Conv_SetInternalCodeset("UTF-8");
       +  LocaleIsUTF8 = TRUE;
          WantUTF8Errors(TRUE);
        #endif
        
 (DIR) diff --git a/src/dopewars.c b/src/dopewars.c
       t@@ -101,6 +101,7 @@ gboolean Daemonize = TRUE;
        
        gchar *WebBrowser = NULL;
        gint ConfigErrors = 0;
       +gboolean LocaleIsUTF8 = FALSE;
        
        int NumLocation = 0, NumGun = 0, NumCop = 0, NumDrug = 0, NumSubway = 0;
        int NumPlaying = 0, NumStoppedTo = 0;
       t@@ -2924,9 +2925,11 @@ int main(int argc, char *argv[])
        {
          struct CMDLINE *cmdline;
        #ifdef ENABLE_NLS
       +  const char *charset;
          setlocale(LC_ALL, "");
          bindtextdomain(PACKAGE, LOCALEDIR);
          textdomain(PACKAGE);
       +  LocaleIsUTF8 = g_get_charset(&charset);
        #endif
          WantUTF8Errors(FALSE);
          g_log_set_handler(NULL, LogMask(), DefaultLogMessage, NULL);
 (DIR) diff --git a/src/dopewars.h b/src/dopewars.h
       t@@ -371,6 +371,7 @@ extern GSList *ServerList;
        extern GScannerConfig ScannerConfig;
        extern struct LOG Log;
        extern gint ConfigErrors;
       +extern gboolean LocaleIsUTF8;
        
        GSList *RemovePlayer(Player *Play, GSList *First);
        Player *GetPlayerByID(guint ID, GSList *First);
 (DIR) diff --git a/src/winmain.c b/src/winmain.c
       t@@ -283,6 +283,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
          setlocale(LC_ALL, "");
          bindtextdomain(PACKAGE, LOCALEDIR);
          textdomain(PACKAGE);
       +  LocaleIsUTF8 = g_get_charset(&charset);
        #endif
        
          /* Informational comment placed at the start of the Windows log file