[MPlayer-dev-eng] [PATCH] localize with gettext (libintl)

Torinthiel torinthiel at megapolis.pl
Wed Nov 29 23:39:14 CET 2006


On Wed, Nov 29, 2006 at 11:17:23PM +0100, Ötvös Attila wrote:
> Hi All.
> 
> mplayer-add:
> Makefile and genpo script:
> genarate ??.po from help_mp-??.h files

Ages ago I've sent a program to convert help* to *.po (based on another
by Jiri Svoboda). IT still works, and is attached to this mail. Makefile
to generate .po and .mo files is as well. Only things missing was AFAIR
installing the .mo files, linking the Makefile into main build chain and
some init. IIRC mp_msg used to even put messages through gettext, but
now it's gone, maybe looking through svnlogs could shed some light onto
this. And there's the problem on convincing some opposing devs, although
that probably can be done if the feature can be disabled on ./configure
run (so that nothing new is built then).

One thing however: I'd be very glad if you could make it in a way that
doesn't require installing the .mo files. I never install MPlayer,
always use it directly from build dir, and AFAIK a lot of people do so
as well. 
I've once managed to write a program that could use .mo files from
either builddir (almost, with some easy to make symlinks) or installdir
(choice had to be made on config, which is OK by me), can send this as
well.
Torinthiel

-- 
 Waclaw "Torinthiel" Schiller       GG#: 3073512
   torinthiel(at)megapolis(dot)pl
   gpg: 0906A2CE fpr: EE3E DFB4 C4D6 E22E 8999  D714 7CEB CDDC 0906 A2CE
 "No classmates may be used during this examination"
-------------- next part --------------
include ../config.mak

POFILES:=bg.po cs.po de.po es.po hu.po it.po pl.po ru.po sk.po sv.po uk.po zh_CN.po
MOFILES:=$(subst po,mo, $(POFILES))

CFLAGS  = $(OPTFLAGS) -I. -Wall $(EXTRA_INC)

.SUFFIXES: .c .o .po .mo

.PHONY: all clean distclean po mo
all: po

po: $(POFILES)
mo: $(MOFILES)

$(POFILES): %.po: help_mp-%.h pogen
	./pogen $(patsubst help_mp-%.h,%,$<) `cat $<.charset 2>/dev/null`

$(MOFILES): %.mo: %.po
	msgfmt -o $@ $<

pogen: pogen.o
	$(CC) $(CFLAGS) -o $@ $^

pogen.o: pogen.c
	$(CC) -c $(CFLAGS) -o $@ $<

clean distclean:
	rm -f pogen pogen.o $(POFILES) $(MOFILES)

########
# creates a sample file.
messages:
	xgettext -a --no-location --no-wrap help_mp-en.h
messages.mo: messages
	msgfmt $<.po

-------------- next part --------------
/* Program for translating header files to .po files
 *  Original by:
 *    Jiri Svoboda <jiri(dot)svoboda(at)seznam(dot)cz>
 *  Modified for multiple languages by:
 *    Waclaw Schiller <torinthiel(at)megapolis(dot)pl>
 * usage: pogen lang optional_charset
 */
#include <stdio.h>
#include <string.h>


#undef DEBUG
//#define DEBUG 1
#ifdef DEBUG
#define LOG(...) printf(__VA_ARGS__)
#else
#define LOG(...)
#endif

FILE *ine; // original file
FILE *inl; // translation file
FILE *out; // output .po
FILE *cfg; // config.h file

static char l[1024];
static char l2[1024];
static char str[1024];
static char str2[1024];
static char *t = NULL;
static char *n = 0;
int mode = 0;
static char *c;

int defined(char *def)
{
    int ret;
//    printf("Watch for define: %s", def);
    ret = 0;
    rewind(cfg);
    while ((t = fgets(l2, 1023, cfg)))
    {
	sscanf(l2, "#define %s", str2);
	if (strcmp(str2, def) == 0)
        {
	    ret = 1;
	    break;
	}
    };
//    if (ret) {
//	printf(" ... found \n");
//    } else {
//	printf(" ... not found\n");
//    }
    return ret;
}

void hlptxt(FILE *file, char *mask)
{
rewind(file);
// find help text beginning
    while ((t = fgets(l, 1023, file))) {
	if (sscanf(l, mask, str))
	    break;
//    printf("%s\n",l);
    }
    mode = 0;
    while ((t = fgets(l, 1023, file))) {
	// cut off comments from line
	c = strstr(l, "//");
        n=strrchr(l, '\"');
        if (c && c>n)
        {
		*c = '\n';
		*(c+1) = 0;
	}

	if (l[strlen(l) - 2] == ';') {
	    l[strlen(l) - 2] = 0;
	    fprintf(out, "%s\n", l);
	    break;
	}
// obsolente
	if (sscanf(l, "#define MSGTR_%s", str))
	    break;
	if (mode == 9)
	    break;
// end obsolente

//    if ((l[0]=='\"')||(l[0]=='#')) switch (mode) {
	if (strlen(l))
	    switch (mode) {
	    case 0:		//normal - watch for #ifdef
		//#endif or blank for end
		if (sscanf(l, "#ifdef %s", str)) {
//              printf("#ifdef %s found ...\n",str);
		    if (defined(str)) {
			mode = 1;
		    } else {
			mode = 3;
		    };
		} else {
		    if (sscanf(l, "#endif %s", str)) {
			mode = 9;
			break;
		    };
		    if (strlen(l) == 0) {
			mode = 9;
			break;
		    };
		    fprintf(out, "%s", l);
		}
		break;
	    case 1:		//ifdef active - wath for else or endif
		if (strstr(l, "#else"))
		    mode = 2;
		if (strstr(l, "#endif"))
		    mode = 0;
		if (mode == 1)
		    fprintf(out, "%s", l);
		break;
	    case 2:		//ifdef was active - skipping after else - watch for endif
		if (strstr(l, "#endif")) {
		    mode = 0;
		} else {
//              fprintf(out,"%s",l);
		}
		break;
	    case 3:		//ifdef not true - skipping after if - watch for else or endif
		if (strstr(l, "#else")) {
		    mode = 4;
		} else if (strstr(l, "#endif")) {
		    mode = 0;
		} else {
//              fprintf(out,"%s",l);
		}
		break;
	    case 4:		//ifdef not true - else active - watch for endif
		if (strstr(l, "#endif")) {
		    mode = 0;
		} else {
		    fprintf(out, "%s", l);
		}
		break;
	    }
    }

}



int main(int argc, char **argv)
{
  int cont=0;
  int print;
  char name[1024];
  char bufen[8192];
  char buftr[8192];
  
  LOG("Prg started.\n");

  ine = fopen("help_mp-en.h", "r");
  if (!ine)
  {
    fprintf(stderr, "Could not open eng file\n");
    exit(1);
  } /* if */
  LOG("EN file opened.\n");

  sprintf(name, "help_mp-%s.h", argv[1]);
  inl = fopen(name, "rb");
  if (!inl)
  {
    fprintf(stderr, "Could not open trans file\n");
    fclose(ine);
    exit(2);
  }
  LOG("Translated MSG file opened.\n");

  sprintf(name, "%s.po", argv[1]);
  out = fopen(name, "w");
  if (!out)
  {
    fprintf(stderr, "Could not open po file\n");
    fclose(ine);
    fclose(inl);
    exit(3);
  }
  LOG("PO file opened.\n");

  cfg = fopen("../config.h", "r");
  if (!cfg)
  {
    fclose(ine);
    fclose(inl);
    fclose(out);
    printf("Could not open cfg file\n");
    exit(4);
  }

  LOG("CFG file opened.\n");

  fprintf(out, "# PO file autogenerated from help_mp-%s.h\n#\n", argv[1]);
  fprintf(out, "msgid \"\"\n");
  fprintf(out, "msgstr \"\"\n");
  fprintf(out, "\"Project-Id-Version: mplayer\\n\"\n");
//fprintf(out,"\"POT-Creation-Date: 2002-04-26 15:31+0200\n\"\n");
//fprintf(out,"\"PO-Revision-Date: 2002-05-07 20:00+0200\n\"\n");
//fprintf(out, "\"Last-Translator: Jiri Svoboda <Jiri.Svoboda at seznam.cz>\\n\"\n");
  fprintf(out, "\"MIME-Version: 1.0\\n\"\n");
  if (argc > 2)
    fprintf(out, "\"Content-Type: text/plain; charset=%s\\n\"\n", argv[2]);
  fprintf(out, "\"Content-Transfer-Encoding: 8bit\\n\"\n");
  fprintf(out, "\n");
  LOG("Header in PO file written.\n");


  LOG("help pass starting\n");
// process the english part
  fprintf(out, "#. help_text\n#, c-format\nmsgid \"\"\n");
  hlptxt(ine,"static char help_text%s");

// process the translated part
  fprintf(out, "\nmsgstr \"\"\n");
  hlptxt(inl,"static char help_text%s");
  fprintf(out, "\n");

  LOG("#define pass starting\n");
// Go round the English file, and process each #define
  while (fgets(l, 1023, ine))
  {
  LOG("Scanning ... ");
    if ((sscanf(l, "#define MSGTR_%s", str)))
    {
      print=0;
      // Found #define. Now process it
      LOG("found source string id %s ", str);
      
      // First copy whole #define body into bufen
      c=strstr(l, "//");
      n=strrchr(l, '\"');
      if (c && c>n)
      {
        *c='\n';
        *(c+1)='\0';
      } /* if */
      if (l[strlen(l)-2]=='\\')
      {
        cont=1;
        strcpy(l+strlen(l)-2, "\n");
      } /* if */
      strcpy(bufen, l+14+strlen(str));
      // read multiline description
      while (cont)
      {
        fgets(l, 1023, ine);
        c=strstr(l, "//");
        n=strrchr(l, '\"');
        if (c && c>n)
        {
          *c='\n';
          *(c+1)='\0';
        } /* if */
        if (l[strlen(l)-2]=='\\')
        {
          cont=1;
          strcpy(l+strlen(l)-2, "\n");
        } /* if */
        else
          cont=0;
        strcat(bufen, l);
      } /* while */
      if (!strchr(l, '\"'))
        continue;
      LOG(" EN-ok");
    
      // Now we have to find the translation
      rewind(inl);
      while (fgets(l, 1023, inl))
      {
        /**********************************/
        if ((sscanf(l, "#define MSGTR_%s", str2))&&(!strcmp(str, str2)))
        {
          print=1;
          // Found matching #define. Now process it
          LOG(" Trans found");
      
          // First copy whole #define body into bufen
          c=strstr(l, "//");
          n=strrchr(l, '\"');
          if (c && c>n)
          {
            *c='\n';
            *(c+1)='\0';
          } /* if */
          if (l[strlen(l)-2]=='\\')
          {
            cont=1;
            strcpy(l+strlen(l)-2, "\n");
          } /* if */
          strcpy(buftr, l+14+strlen(str));
          // read multiline description
          while (cont)
          {
            fgets(l, 1023, inl);
            c=strstr(l, "//");
            n=strrchr(l, '\"');
            if (c && c>n)
            {
              *c='\n';
              *(c+1)='\0';
            } /* if */
            if (l[strlen(l)-2]=='\\')
            {
              cont=1;
              strcpy(l+strlen(l)-2, "\n");
            } /* if */
            else
              cont=0;
            strcat(buftr, l);
          } /* while */
          break;
        } /* if */
      } /* while */
      LOG(" TRANS-ok\n");

      if (print)
        fprintf(out, "\n#. MSGTR_%s\n#, c-format\nmsgid %smsgstr%s", str, bufen, buftr);
    } /* if */
  } /* while */

  fclose(cfg);
  fclose(inl);
  fclose(ine);
  fclose(out);
  LOG("Finished\n");
  return 0;
} /* main */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20061129/0379760c/attachment.pgp>


More information about the MPlayer-dev-eng mailing list