ttstring.c - vaccinewars - be a doctor and try to vaccinate the world
git clone git://src.adamsgaard.dk/vaccinewars
Log
Files
Refs
README
LICENSE
---
ttstring.c (8237B)
---
     1 /************************************************************************
     2  * tstring.c      "Translated string" wrappers for dopewars             *
     3  * Copyright (C)  1998-2021  Ben Webb                                   *
     4  *                Email: benwebb@users.sf.net                           *
     5  *                WWW: https://dopewars.sourceforge.io/                 *
     6  *                                                                      *
     7  * This program is free software; you can redistribute it and/or        *
     8  * modify it under the terms of the GNU General Public License          *
     9  * as published by the Free Software Foundation; either version 2       *
    10  * of the License, or (at your option) any later version.               *
    11  *                                                                      *
    12  * This program is distributed in the hope that it will be useful,      *
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
    15  * GNU General Public License for more details.                         *
    16  *                                                                      *
    17  * You should have received a copy of the GNU General Public License    *
    18  * along with this program; if not, write to the Free Software          *
    19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,               *
    20  *                   MA  02111-1307, USA.                               *
    21  ************************************************************************/
    22 
    23 #include 
    24 #include 
    25 #include 
    26 
    27 #ifdef HAVE_CONFIG_H
    28 #include 
    29 #endif
    30 
    31 #include 
    32 #include "dopewars.h"
    33 #include "message.h"
    34 #include "tstring.h"
    35 
    36 typedef struct _FmtData {
    37   union {
    38     int IntVal;
    39     price_t PriceVal;
    40     char CharVal;
    41     char *StrVal;
    42   } data;
    43   char Type;
    44 } FmtData;
    45 
    46 gchar *GetDefaultTString(gchar *tstring)
    47 {
    48   gchar *dstr, *pt;
    49 
    50   dstr = g_strdup(tstring);
    51   pt = strchr(dstr, '_');
    52   if (pt)
    53     *pt = '\0';
    54   return dstr;
    55 }
    56 
    57 gchar *GetTranslatedString(gchar *str, gchar *code, gboolean Caps)
    58 {
    59   gchar *dstr, *pt, *tstr, *Default, *tcode;
    60 
    61   dstr = g_strdup(str);
    62   g_strdelimit(dstr, "_", '^');
    63   pt = dstr;
    64   Default = GetNextWord(&pt, "");
    65   tstr = NULL;
    66 
    67   while (1) {
    68     tcode = GetNextWord(&pt, NULL);
    69     tstr = GetNextWord(&pt, "");
    70     if (!tcode) {
    71       tstr = NULL;
    72       break;
    73     }
    74     if (strcmp(tcode, code) == 0) {
    75       break;
    76     } else
    77       tstr = NULL;
    78   }
    79 
    80   if (tstr) {
    81     if (Caps)
    82       tstr = InitialCaps(tstr);
    83     else
    84       tstr = g_strdup(tstr);
    85   } else {
    86     if (Caps)
    87       tstr = InitialCaps(Default);
    88     else
    89       tstr = g_strdup(Default);
    90   }
    91 
    92   g_free(dstr);
    93   return tstr;
    94 }
    95 
    96 void GetNextFormat(guint *Index, gchar *str, int *StartPos,
    97                    int *EndPos, int *FmtPos, gchar *Type, int *ArgNum,
    98                    int *Wid, int *Prec, char *Code)
    99 {
   100   int anum, wid, prec;
   101   guint i;
   102   gchar type;
   103 
   104   *StartPos = -1;
   105   *EndPos = *FmtPos = *ArgNum = *Wid = *Prec = 0;
   106   *Type = 0;
   107   Code[0] = 0;
   108   anum = wid = prec = 0;
   109   i = *Index;
   110   while (str[i]) {
   111     if (str[i] == '%') {
   112       *StartPos = *EndPos = i++;
   113       while (strchr("#0- +'", str[i]))
   114         i++;                    /* Skip flag characters */
   115       while (str[i] >= '0' && str[i] <= '9')
   116         wid = wid * 10 + str[i++] - '0';
   117       if (str[i] == '$') {
   118         *EndPos = i;
   119         i++;
   120         anum = wid;
   121         wid = 0;
   122         while (strchr("#0- +'", str[i]))
   123           i++;                  /* Skip flag characters */
   124         while (str[i] >= '0' && str[i] <= '9')
   125           wid = wid * 10 + str[i++] - '0';
   126       }
   127       if (str[i] == '.') {
   128         i++;
   129         while (str[i] >= '0' && str[i] <= '9')
   130           prec = prec * 10 + str[i++] - '0';
   131       }
   132       *FmtPos = i;
   133       type = str[i];
   134       if ((type == 'T' || type == 't') && i + 2 < strlen(str)) {
   135         Code[0] = str[i + 1];
   136         Code[1] = str[i + 2];
   137         Code[2] = 0;
   138         i += 3;
   139       } else if (type == '/') {
   140         i++;
   141         while (str[i] != '\0' && str[i] != '/')
   142           i++;
   143         if (str[i] == '/')
   144           i++;
   145       } else
   146         i++;
   147       *ArgNum = anum;
   148       *Wid = wid;
   149       *Prec = prec;
   150       *Index = i;
   151       *Type = type;
   152       return;
   153     } else
   154       i++;
   155   }
   156   *Index = i;
   157 }
   158 
   159 gchar *HandleTFmt(gchar *format, va_list va)
   160 {
   161   int StrInd, StartPos, EndPos, FmtPos, Wid, Prec, ArgNum, DefaultArgNum;
   162   guint i;
   163   char Code[3], Type;
   164   gchar *retstr, *fstr;
   165   GString *string, *tmpfmt;
   166   GArray *arr;
   167   FmtData *fdat;
   168 
   169   string = g_string_new("");
   170   tmpfmt = g_string_new("");
   171 
   172   arr = g_array_new(FALSE, TRUE, sizeof(FmtData));
   173   i = DefaultArgNum = 0;
   174   while (i < strlen(format)) {
   175     GetNextFormat(&i, format, &StartPos, &EndPos, &FmtPos, &Type, &ArgNum,
   176                   &Wid, &Prec, Code);
   177     if (StartPos == -1)
   178       break;
   179     if (ArgNum == 0)
   180       ArgNum = ++DefaultArgNum;
   181     if (ArgNum > arr->len) {
   182       g_array_set_size(arr, ArgNum);
   183     }
   184     g_array_index(arr, FmtData, ArgNum - 1).Type = Type;
   185   }
   186   for (i = 0; i < arr->len; i++) {
   187     fdat = &g_array_index(arr, FmtData, i);
   188 
   189     switch (fdat->Type) {
   190     case '\0':
   191       g_error("Incomplete format string!");
   192       break;
   193     case 'd':
   194       fdat->data.IntVal = va_arg(va, int);
   195       break;
   196     case 'P':
   197       fdat->data.PriceVal = va_arg(va, price_t);
   198       break;
   199     case 'c':
   200       fdat->data.CharVal = (char)va_arg(va, int);
   201       break;
   202     case 's':
   203     case 't':
   204     case 'T':
   205       fdat->data.StrVal = va_arg(va, char *);
   206       break;
   207     case '%':
   208     case '/':
   209       break;                    /* No special action for %% or %/.../ */
   210     default:
   211       g_error("Unknown format type %c!", fdat->Type);
   212     }
   213   }
   214   i = DefaultArgNum = 0;
   215   while (i < strlen(format)) {
   216     StrInd = i;
   217     GetNextFormat(&i, format, &StartPos, &EndPos, &FmtPos, &Type, &ArgNum,
   218                   &Wid, &Prec, Code);
   219     if (StartPos == -1) {
   220       g_string_append(string, &format[StrInd]);
   221       break;
   222     }
   223     while (StrInd < StartPos)
   224       g_string_append_c(string, format[StrInd++]);
   225     if (ArgNum == 0)
   226       ArgNum = ++DefaultArgNum;
   227     g_string_assign(tmpfmt, "%");
   228     EndPos++;
   229     while (EndPos < FmtPos)
   230       g_string_append_c(tmpfmt, format[EndPos++]);
   231     if (Type == 'T' || Type == 't' || Type == 'P')
   232       g_string_append_c(tmpfmt, 's');
   233     else
   234       g_string_append_c(tmpfmt, Type);
   235     fdat = &g_array_index(arr, FmtData, ArgNum - 1);
   236 
   237     if (Type != fdat->Type)
   238       g_error("Unmatched types!");
   239     switch (Type) {
   240     case 'd':
   241       g_string_append_printf(string, tmpfmt->str, fdat->data.IntVal);
   242       break;
   243     case 'c':
   244       g_string_append_printf(string, tmpfmt->str, fdat->data.CharVal);
   245       break;
   246     case 'P':
   247       fstr = FormatPrice(fdat->data.PriceVal);
   248       g_string_append_printf(string, tmpfmt->str, fstr);
   249       g_free(fstr);
   250       break;
   251     case 't':
   252     case 'T':
   253       fstr = GetTranslatedString(fdat->data.StrVal, Code, Type == 'T');
   254       g_string_append_printf(string, tmpfmt->str, fstr);
   255       g_free(fstr);
   256       break;
   257     case 's':
   258       g_string_append_printf(string, tmpfmt->str, fdat->data.StrVal);
   259       break;
   260     case '%':
   261       g_string_append_c(string, '%');
   262       break;
   263     }
   264   }
   265   retstr = string->str;
   266   g_array_free(arr, TRUE);
   267   g_string_free(string, FALSE);
   268   g_string_free(tmpfmt, TRUE);
   269   return retstr;
   270 }
   271 
   272 void dpg_print(gchar *format, ...)
   273 {
   274   va_list ap;
   275   gchar *retstr;
   276 
   277   va_start(ap, format);
   278   retstr = HandleTFmt(format, ap);
   279   va_end(ap);
   280   g_print("%s", retstr);
   281   g_free(retstr);
   282 }
   283 
   284 gchar *dpg_strdup_printf(gchar *format, ...)
   285 {
   286   va_list ap;
   287   gchar *retstr;
   288 
   289   va_start(ap, format);
   290   retstr = HandleTFmt(format, ap);
   291   va_end(ap);
   292   return retstr;
   293 }
   294 
   295 void dpg_string_printf(GString *string, gchar *format, ...)
   296 {
   297   va_list ap;
   298   gchar *newstr;
   299 
   300   va_start(ap, format);
   301   newstr = HandleTFmt(format, ap);
   302   g_string_assign(string, newstr);
   303   g_free(newstr);
   304   va_end(ap);
   305 }
   306 
   307 void dpg_string_append_printf(GString *string, gchar *format, ...)
   308 {
   309   va_list ap;
   310   gchar *newstr;
   311 
   312   va_start(ap, format);
   313   newstr = HandleTFmt(format, ap);
   314   g_string_append(string, newstr);
   315   g_free(newstr);
   316   va_end(ap);
   317 }