src/language.c File Reference

#include "main.h"
Include dependency graph for language.c:

Go to the source code of this file.

Data Structures

struct  lang_st
struct  lang_pr
struct  lang_t

Typedefs

typedef struct lang_st lang_sec
typedef struct lang_pr lang_pri
typedef struct lang_t lang_tab

Functions

static int del_lang (char *)
static int add_message (int, char *)
static void recheck_lang_sections (void)
static void read_lang (char *)
void add_lang_section (char *)
int del_lang_section (char *)
int exist_lang_section (char *)
static char * get_specific_langfile (char *, lang_sec *)
static char * get_langfile (lang_sec *)
static int split_lang (char *, char **, char **)
int cmd_loadlanguage (struct userrec *, int, char *)
void add_lang (char *lang)
static int cmd_plslang (struct userrec *u, int idx, char *par)
static int cmd_mnslang (struct userrec *u, int idx, char *par)
static int cmd_plslsec (struct userrec *u, int idx, char *par)
static int cmd_mnslsec (struct userrec *u, int idx, char *par)
static int cmd_relang (struct userrec *u, int idx, char *par)
static int cmd_languagedump (struct userrec *u, int idx, char *par)
char * get_language (int idx)
int expmem_language ()
static int cmd_languagestatus (struct userrec *u, int idx, char *par)
void init_language (int flag)

Variables

struct dcc_tdcc
static lang_tablangtab [64]
static lang_seclangsection = 0
static lang_prilangpriority = 0
static char text [512]
static tcl_cmds langtcls []

Typedef Documentation

typedef struct lang_pr lang_pri
typedef struct lang_st lang_sec
typedef struct lang_t lang_tab

Function Documentation

void add_lang ( char *  lang  ) 

Definition at line 108 of file language.c.

References debug1, lang_pr::lang, lang_pr::next, nmalloc, and NULL.

Referenced by cmd_loadlanguage(), cmd_plslang(), and init_language().

00109 {
00110   lang_pri *lp = langpriority, *lpo = NULL;
00111 
00112   while (lp) {
00113     /* The language already exists, moving to the beginning */
00114     if (!strcmp(lang, lp->lang)) {
00115       /* Already at the front? */
00116       if (!lpo)
00117         return;
00118       lpo->next = lp->next;
00119       lp->next = lpo;
00120       langpriority = lp;
00121       return;
00122     }
00123     lpo = lp;
00124     lp = lp->next;
00125   }
00126 
00127   /* No existing entry, create a new one */
00128   lp = nmalloc(sizeof(lang_pri));
00129   lp->lang = nmalloc(strlen(lang) + 1);
00130   strcpy(lp->lang, lang);
00131   lp->next = NULL;
00132 
00133   /* If we have other entries, point to the beginning of the old list */
00134   if (langpriority)
00135     lp->next = langpriority;
00136   langpriority = lp;
00137   debug1("LANG: Language loaded: %s", lang);
00138 }

Here is the caller graph for this function:

void add_lang_section ( char *  section  ) 

Definition at line 307 of file language.c.

References BASELANG, debug1, get_langfile(), get_specific_langfile(), LOG_MISC, lang_st::next, nfree, nmalloc, NULL, putlog, and read_lang().

00308 {
00309   char *langfile = NULL;
00310   lang_sec *ls, *ols = NULL;
00311   int ok = 0;
00312 
00313   for (ls = langsection; ls; ols = ls, ls = ls->next)
00314     /* Already know of that section? */
00315     if (!strcmp(section, ls->section))
00316       return;
00317 
00318   /* Create new section entry */
00319   ls = nmalloc(sizeof(lang_sec));
00320   ls->section = nmalloc(strlen(section) + 1);
00321   strcpy(ls->section, section);
00322   ls->lang = NULL;
00323   ls->next = NULL;
00324 
00325   /* Connect to existing list of sections */
00326   if (ols)
00327     ols->next = ls;
00328   else
00329     langsection = ls;
00330   debug1("LANG: Section loaded: %s", section);
00331 
00332   /* Always load base language */
00333   langfile = get_specific_langfile(BASELANG, ls);
00334   if (langfile) {
00335     read_lang(langfile);
00336     nfree(langfile);
00337     ok = 1;
00338   }
00339   /* Now overwrite base language with a more preferred one */
00340   langfile = get_langfile(ls);
00341   if (!langfile) {
00342     if (!ok)
00343       putlog(LOG_MISC, "*", "LANG: No lang files found for section %s.",
00344              section);
00345     return;
00346   }
00347   read_lang(langfile);
00348   nfree(langfile);
00349 }

Here is the call graph for this function:

static int add_message ( int  lidx,
char *  ltext 
) [static]

Definition at line 166 of file language.c.

References lang_t::idx, lang_t::next, nfree, nmalloc, and lang_t::text.

Referenced by read_lang().

00167 {
00168   lang_tab *l = langtab[lidx & 63];
00169 
00170   while (l) {
00171     if (l->idx && (l->idx == lidx)) {
00172       nfree(l->text);
00173       l->text = nmalloc(strlen(ltext) + 1);
00174       strcpy(l->text, ltext);
00175       return 1;
00176     }
00177     if (!l->next)
00178       break;
00179     l = l->next;
00180   }
00181   if (l) {
00182     l->next = nmalloc(sizeof(lang_tab));
00183     l = l->next;
00184   } else
00185     l = langtab[lidx & 63] = nmalloc(sizeof(lang_tab));
00186   l->idx = lidx;
00187   l->text = nmalloc(strlen(ltext) + 1);
00188   strcpy(l->text, ltext);
00189   l->next = 0;
00190   return 0;
00191 }

Here is the caller graph for this function:

static int cmd_languagedump ( struct userrec u,
int  idx,
char *  par 
) [static]

Definition at line 525 of file language.c.

References dprintf, get_language, lang_t::idx, int, LOG_CMDS, lang_t::next, NULL, putlog, and lang_t::text.

00526 {
00527   lang_tab *l;
00528   char ltext2[512];
00529   int idx2, i;
00530 
00531   putlog(LOG_CMDS, "*", "#%s# ldump %s", dcc[idx].nick, par);
00532   if (par[0]) {
00533     /* atoi (hence strtol) don't work right here for hex */
00534     if (strlen(par) > 2 && par[0] == '0' && par[1] == 'x')
00535       sscanf(par, "%x", &idx2);
00536     else
00537       idx2 = (int) strtol(par, (char **) NULL, 10);
00538     strcpy(ltext2, get_language(idx2));
00539     dprintf(idx, "0x%x: %s\n", idx2, ltext2);
00540     return 0;
00541   }
00542   dprintf(idx, " LANGIDX TEXT\n");
00543   for (i = 0; i < 64; i++)
00544     for (l = langtab[i]; l; l = l->next)
00545       dprintf(idx, "0x%x   %s\n", l->idx, l->text);
00546   return 0;
00547 }

static int cmd_languagestatus ( struct userrec u,
int  idx,
char *  par 
) [static]

Definition at line 592 of file language.c.

References dprintf, expmem_language(), lang_st::lang, lang_pr::lang, LOG_CMDS, lang_st::next, lang_pr::next, lang_t::next, putlog, and lang_st::section.

00593 {
00594   int ltexts = 0;
00595   register int i, c, maxdepth = 0, used = 0, empty = 0;
00596   lang_tab *l;
00597   lang_sec *ls = langsection;
00598   lang_pri *lp = langpriority;
00599 
00600   putlog(LOG_CMDS, "*", "#%s# lstat %s", dcc[idx].nick, par);
00601   for (i = 0; i < 64; i++) {
00602     c = 0;
00603     for (l = langtab[i]; l; l = l->next)
00604       c++;
00605     if (c > maxdepth)
00606       maxdepth = c;
00607     if (c)
00608       used++;
00609     else
00610       empty++;
00611     ltexts += c;
00612   }
00613   dprintf(idx, "Language code report:\n");
00614   dprintf(idx, "   Table size   : %d bytes\n", expmem_language());
00615   dprintf(idx, "   Text messages: %d\n", ltexts);
00616   dprintf(idx, "   %d used, %d unused, maxdepth %d, avg %f\n",
00617           used, empty, maxdepth, (float) ltexts / 64.0);
00618   if (lp) {
00619     int c = 0;
00620 
00621     dprintf(idx, "   Supported languages:");
00622     for (; lp; lp = lp->next) {
00623       dprintf(idx, "%s %s", c ? "," : "", lp->lang);
00624       c = 1;
00625     }
00626     dprintf(idx, "\n");
00627   }
00628   if (ls) {
00629     dprintf(idx, "\n   SECTION              LANG\n");
00630     dprintf(idx, "   ==============================\n");
00631     for (; ls; ls = ls->next)
00632       dprintf(idx, "   %-20s %s\n", ls->section,
00633               ls->lang ? ls->lang : "<none>");
00634   }
00635   return 0;
00636 }

Here is the call graph for this function:

int cmd_loadlanguage ( struct userrec u,
int  idx,
char *  par 
)

Definition at line 444 of file language.c.

References add_lang(), add_lang_section, DP_LOG, dprintf, LOG_CMDS, nfree, nmalloc, putlog, recheck_lang_sections(), and split_lang().

00445 {
00446   char *section, *lang, *buf;
00447 
00448   dprintf(idx, "Note: This command is obsoleted by +lang.\n");
00449   if (!par || !par[0]) {
00450     dprintf(idx, "Usage: language <section>.<language>\n");
00451     return 0;
00452   }
00453   if (idx != DP_LOG)
00454     putlog(LOG_CMDS, "*", "#%s# language %s", dcc[idx].nick, par);
00455   buf = nmalloc(strlen(par) + 1);
00456   strcpy(buf, par);
00457   if (!split_lang(buf, &lang, &section)) {
00458     nfree(buf);
00459     dprintf(idx, "Invalid parameter %s.\n", par);
00460     return 0;
00461   }
00462   add_lang(lang);
00463   add_lang_section(section);
00464   nfree(buf);
00465   recheck_lang_sections();
00466   return 0;
00467 }

Here is the call graph for this function:

static int cmd_mnslang ( struct userrec u,
int  idx,
char *  par 
) [static]

Definition at line 481 of file language.c.

References del_lang(), dprintf, LOG_CMDS, putlog, and recheck_lang_sections().

00482 {
00483   if (!par || !par[0]) {
00484     dprintf(idx, "Usage: -lang <language>\n");
00485     return 0;
00486   }
00487   putlog(LOG_CMDS, "*", "#%s# -lang %s", dcc[idx].nick, par);
00488   if (!del_lang(par))
00489     dprintf(idx, "Language %s not found.\n", par);
00490   else
00491     recheck_lang_sections();
00492   return 0;
00493 }

Here is the call graph for this function:

static int cmd_mnslsec ( struct userrec u,
int  idx,
char *  par 
) [static]

Definition at line 506 of file language.c.

References del_lang_section, dprintf, LOG_CMDS, and putlog.

00507 {
00508   if (!par || !par[0]) {
00509     dprintf(idx, "Usage: -lsec <section>\n");
00510     return 0;
00511   }
00512   putlog(LOG_CMDS, "*", "#%s# -lsec %s", dcc[idx].nick, par);
00513   if (!del_lang_section(par))
00514     dprintf(idx, "Section %s not found.\n", par);
00515   return 0;
00516 }

static int cmd_plslang ( struct userrec u,
int  idx,
char *  par 
) [static]

Definition at line 469 of file language.c.

References add_lang(), dprintf, LOG_CMDS, putlog, and recheck_lang_sections().

00470 {
00471   if (!par || !par[0]) {
00472     dprintf(idx, "Usage: +lang <language>\n");
00473     return 0;
00474   }
00475   putlog(LOG_CMDS, "*", "#%s# +lang %s", dcc[idx].nick, par);
00476   add_lang(par);
00477   recheck_lang_sections();
00478   return 0;
00479 }

Here is the call graph for this function:

static int cmd_plslsec ( struct userrec u,
int  idx,
char *  par 
) [static]

Definition at line 495 of file language.c.

References add_lang_section, dprintf, LOG_CMDS, and putlog.

00496 {
00497   if (!par || !par[0]) {
00498     dprintf(idx, "Usage: +lsec <section>\n");
00499     return 0;
00500   }
00501   putlog(LOG_CMDS, "*", "#%s# +lsec %s", dcc[idx].nick, par);
00502   add_lang_section(par);
00503   return 0;
00504 }

static int cmd_relang ( struct userrec u,
int  idx,
char *  par 
) [static]

Definition at line 518 of file language.c.

References dprintf, and recheck_lang_sections().

00519 {
00520   dprintf(idx, "Rechecking language sections...\n");
00521   recheck_lang_sections();
00522   return 0;
00523 }

Here is the call graph for this function:

static int del_lang ( char *  lang  )  [static]

Definition at line 142 of file language.c.

References debug1, lang_pr::lang, lang_pr::next, nfree, and NULL.

Referenced by cmd_mnslang().

00143 {
00144   lang_pri *lp = langpriority, *lpo = NULL;
00145 
00146   while (lp) {
00147     /* Found the language? */
00148     if (!strcmp(lang, lp->lang)) {
00149       if (lpo)
00150         lpo->next = lp->next;
00151       else
00152         langpriority = lp->next;
00153       if (lp->lang)
00154         nfree(lp->lang);
00155       nfree(lp);
00156       debug1("LANG: Language unloaded: %s", lang);
00157       return 1;
00158     }
00159     lpo = lp;
00160     lp = lp->next;
00161   }
00162   /* Language not found */
00163   return 0;
00164 }

Here is the caller graph for this function:

int del_lang_section ( char *  section  ) 

Definition at line 351 of file language.c.

References debug1, lang_st::next, nfree, and NULL.

00352 {
00353   lang_sec *ls, *ols;
00354 
00355   for (ls = langsection, ols = NULL; ls; ols = ls, ls = ls->next)
00356     if (ls->section && !strcmp(ls->section, section)) {
00357       if (ols)
00358         ols->next = ls->next;
00359       else
00360         langsection = ls->next;
00361       nfree(ls->section);
00362       if (ls->lang)
00363         nfree(ls->lang);
00364       nfree(ls);
00365       debug1("LANG: Section unloaded: %s", section);
00366       return 1;
00367     }
00368   return 0;
00369 }

int exist_lang_section ( char *  section  ) 

Definition at line 294 of file language.c.

References lang_st::next, and lang_st::section.

00295 {
00296   lang_sec *ls;
00297 
00298   for (ls = langsection; ls; ls = ls->next)
00299     if (!strcmp(section, ls->section))
00300       return 1;
00301   return 0;
00302 }

int expmem_language (  ) 

Definition at line 563 of file language.c.

References lang_pr::lang, lang_st::lang, lang_pr::next, lang_st::next, lang_t::next, lang_st::section, and lang_t::text.

Referenced by cmd_languagestatus(), debug_mem_to_dcc(), and expected_memory().

00564 {
00565   lang_tab *l;
00566   lang_sec *ls;
00567   lang_pri *lp;
00568   int i, size = 0;
00569 
00570   for (i = 0; i < 64; i++)
00571     for (l = langtab[i]; l; l = l->next) {
00572       size += sizeof(lang_tab);
00573       size += (strlen(l->text) + 1);
00574     }
00575   for (ls = langsection; ls; ls = ls->next) {
00576     size += sizeof(lang_sec);
00577     if (ls->section)
00578       size += strlen(ls->section) + 1;
00579     if (ls->lang)
00580       size += strlen(ls->lang) + 1;
00581   }
00582   for (lp = langpriority; lp; lp = lp->next) {
00583     size += sizeof(lang_pri);
00584     if (lp->lang)
00585       size += strlen(lp->lang) + 1;
00586   }
00587   return size;
00588 }

Here is the caller graph for this function:

static char * get_langfile ( lang_sec sec  )  [static]

Definition at line 396 of file language.c.

References get_specific_langfile(), lang_pr::lang, lang_st::lang, lang_pr::next, nfree, and NULL.

Referenced by add_lang_section(), and recheck_lang_sections().

00397 {
00398   char *langfile;
00399   lang_pri *lp;
00400 
00401   for (lp = langpriority; lp; lp = lp->next) {
00402     /* There is no need to reload the same language */
00403     if (sec->lang && !strcmp(sec->lang, lp->lang))
00404       return NULL;
00405     langfile = get_specific_langfile(lp->lang, sec);
00406     if (langfile)
00407       return langfile;
00408   }
00409   /* We did not find any files, clear the language field */
00410   if (sec->lang)
00411     nfree(sec->lang);
00412   sec->lang = NULL;
00413   return NULL;
00414 }

Here is the call graph for this function:

Here is the caller graph for this function:

char* get_language ( int  idx  ) 

Definition at line 550 of file language.c.

References egg_snprintf, lang_t::idx, lang_t::next, text, and lang_t::text.

00551 {
00552   lang_tab *l;
00553 
00554   if (!idx)
00555     return "MSG-0-";
00556   for (l = langtab[idx & 63]; l; l = l->next)
00557     if (idx == l->idx)
00558       return l->text;
00559   egg_snprintf(text, sizeof text, "MSG%03X", idx);
00560   return text;
00561 }

static char * get_specific_langfile ( char *  language,
lang_sec sec 
) [static]

Definition at line 371 of file language.c.

References file_readable, lang_st::lang, LANGDIR, nfree, nmalloc, nrealloc, NULL, and lang_st::section.

Referenced by add_lang_section(), and get_langfile().

00372 {
00373   char *ldir = getenv("EGG_LANGDIR");
00374   char *langfile;
00375 
00376   if (!ldir)
00377     ldir = LANGDIR;
00378   langfile = nmalloc(strlen(ldir) + strlen(sec->section) + strlen(language) +
00379              8);
00380   sprintf(langfile, "%s/%s.%s.lang", ldir, sec->section, language);
00381 
00382   if (file_readable(langfile)) {
00383     /* Save language used for this section */
00384     sec->lang = nrealloc(sec->lang, strlen(language) + 1);
00385     strcpy(sec->lang, language);
00386     return langfile;
00387   }
00388 
00389   nfree(langfile);
00390   return NULL;
00391 }

Here is the caller graph for this function:

void init_language ( int  flag  ) 

Definition at line 734 of file language.c.

References add_builtins, add_lang(), add_lang_section, add_tcl_commands, BASELANG, and H_dcc.

Referenced by main(), and mainloop().

00735 {
00736   int i;
00737   char *deflang;
00738 
00739   if (flag) {
00740     for (i = 0; i < 32; i++)
00741       langtab[i] = 0;
00742     /* The default language is always BASELANG as language files are
00743      * gauranteed to exist in that language.
00744      */
00745     add_lang(BASELANG);
00746     /* Let the user choose a different, preferred language */
00747     deflang = getenv("EGG_LANG");
00748     if (deflang)
00749       add_lang(deflang);
00750     add_lang_section("core");
00751   } else {
00752     add_tcl_commands(langtcls);
00753     add_builtins(H_dcc, langdcc);
00754   }
00755 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void read_lang ( char *  langfile  )  [static]

Definition at line 213 of file language.c.

References add_message(), debug2, debug3, LOG_MISC, nfree, nmalloc, nrealloc, NULL, and putlog.

Referenced by add_lang_section(), and recheck_lang_sections().

00214 {
00215   FILE *FLANG;
00216   char lbuf[512];
00217   char *ltext = NULL;
00218   char *ctmp, *ctmp1;
00219   int lidx;
00220   int lnew = 1;
00221   int lline = 1;
00222   int lskip = 0;
00223   int ltexts = 0;
00224   int ladd = 0, lupdate = 0;
00225 
00226   FLANG = fopen(langfile, "r");
00227   if (FLANG == NULL) {
00228     putlog(LOG_MISC, "*", "LANG: unexpected: reading from file %s failed.",
00229            langfile);
00230     return;
00231   }
00232 
00233   for (*(ltext = nmalloc(sizeof lbuf)) = 0; fgets(lbuf, sizeof lbuf, FLANG);
00234        ltext = nrealloc(ltext, strlen(ltext) + sizeof lbuf), lskip = 0) {
00235     if (lnew) {
00236       if ((lbuf[0] == '#') || (sscanf(lbuf, "%s", ltext) == EOF))
00237         lskip = 1;
00238       else if (sscanf(lbuf, "0x%x,", &lidx) != 1) {
00239         putlog(LOG_MISC, "*", "LANG: Malformed text line in %s at %d.",
00240                langfile, lline);
00241         lskip = 1;
00242       }
00243       if (lskip) {
00244         while (!strchr(lbuf, '\n')) {
00245           fgets(lbuf, 511, FLANG);
00246           lline++;
00247         }
00248         lline++;
00249         lnew = 1;
00250         continue;
00251       }
00252       strcpy(ltext, strchr(lbuf, ',') + 1);
00253     } else
00254       strcpy(strchr(ltext, 0), lbuf);
00255     if ((ctmp = strchr(ltext, '\n'))) {
00256       lline++;
00257       *ctmp = 0;
00258       if (ctmp[-1] == '\\') {
00259         lnew = 0;
00260         ctmp[-1] = 0;
00261       } else {
00262         ltexts++;
00263         lnew = 1;
00264         /* Convert literal \n and \t escapes */
00265         for (ctmp1 = ctmp = ltext; *ctmp1; ctmp++, ctmp1++) {
00266           if ((*ctmp1 == '\\') && ctmp1[1] == 'n') {
00267             *ctmp = '\n';
00268             ctmp1++;
00269           } else if ((*ctmp1 == '\\') && ctmp1[1] == 't') {
00270             *ctmp = '\t';
00271             ctmp1++;
00272           } else
00273             *ctmp = *ctmp1;
00274         }
00275         *ctmp = 0;
00276         if (add_message(lidx, ltext)) {
00277           lupdate++;
00278         } else
00279           ladd++;
00280       }
00281     } else
00282       lnew = 0;
00283   }
00284   nfree(ltext);
00285   fclose(FLANG);
00286 
00287   debug3("LANG: %d messages of %d lines loaded from %s", ltexts, lline,
00288          langfile);
00289   debug2("LANG: %d adds, %d updates to message table", ladd, lupdate);
00290 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void recheck_lang_sections ( void   )  [static]

Definition at line 196 of file language.c.

References get_langfile(), lang_st::next, nfree, read_lang(), and lang_st::section.

Referenced by cmd_loadlanguage(), cmd_mnslang(), cmd_plslang(), and cmd_relang().

00197 {
00198   lang_sec *ls;
00199   char *langfile;
00200 
00201   for (ls = langsection; ls && ls->section; ls = ls->next) {
00202     langfile = get_langfile(ls);
00203     /* Found a language with a more preferred language? */
00204     if (langfile) {
00205       read_lang(langfile);
00206       nfree(langfile);
00207     }
00208   }
00209 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int split_lang ( char *  par,
char **  lang,
char **  section 
) [static]

Definition at line 420 of file language.c.

Referenced by cmd_loadlanguage().

00421 {
00422   char *p;
00423 
00424   p = strrchr(par, '/');
00425   /* path attached? */
00426   if (p)
00427     *section = p + 1;
00428   else
00429     *section = par;
00430   p = strchr(*section, '.');
00431   if (p)
00432     p[0] = 0;
00433   else
00434     return 0;
00435   *lang = p + 1;
00436   p = strstr(*lang, ".lang");
00437   if (p)
00438     p[0] = 0;
00439   return 1;
00440 }

Here is the caller graph for this function:


Variable Documentation

struct dcc_t* dcc

Definition at line 46 of file dcc.c.

lang_pri* langpriority = 0 [static]

Definition at line 90 of file language.c.

lang_sec* langsection = 0 [static]

Definition at line 89 of file language.c.

lang_tab* langtab[64] [static]

Definition at line 88 of file language.c.

tcl_cmds langtcls[] [static]
Initial value:
 {
  {"language",             tcl_language},
  {"addlang",               tcl_plslang},
  {"dellang",               tcl_mnslang},
  {"addlangsection", tcl_addlangsection},
  {"dellangsection", tcl_dellangsection},
  {"relang",                 tcl_relang},
  { 0 ,                            0 }
}

Definition at line 724 of file language.c.

char text[512] [static]

Definition at line 549 of file language.c.

Referenced by get_language().


Generated on 7 Sep 2016 for Eggdrop by  doxygen 1.6.1