prev/next label fix in viewer, inout highlight, modify folder layout, ffmpeg scan...
[goodguy/history.git] / cinelerra-5.1 / po / xlat.C
index 67701bb9875ee155e9fc67bf3a1a95adb36f16c2..1aa1881fe250babb284bf83095f9bf544c97eaf9 100644 (file)
@@ -62,21 +62,21 @@ static bool is_opnr(int ch)
   return 0;
 }
 
-// converts libreoffice csv to string (with quotes attached)
+// converts libreoffice csv stuttered quoted string (with quotes attached)
 //  quote marks only
 static void xlat1(uint8_t *&in, uint8_t *out)
 {
   uint8_t *ibp = in, *obp = out;
-  unsigned ch;
+  unsigned ch, lch = 0;
   if( (ch=wnext(in)) == '\"' ) { 
     bool is_nested = in[0] == '\"' && in[1] == '\"';
     while( (ch=wnext(in)) != 0 ) {
-      if( ch == '\"' ) {
+      if( ch == '\"' && lch != '\\' ) {
         uint8_t *bp = in;
         unsigned nch = wnext(in);
         if( nch != '\"' ) { in = bp;  break; }
       }
-      wnext(out, ch);
+      wnext(out, lch = ch);
     }
     if( is_nested && ch == '"' ) {
       while( out > obp && *(out-1) == ' ' ) --out;
@@ -108,19 +108,22 @@ static inline unsigned gch(uint8_t *&in) {
 // converts string (with opn/cls attached) to c string
 static void xlat2(uint8_t *in, uint8_t *out)
 {
-  uint8_t *obp = out;
-  unsigned lch = 0, ch = gch(in);
-  if( ch ) {
-    if( !is_opnr(ch) ) wnext(out, ch);
+  unsigned lch = gch(in), sep = 0, rch = 0, ch;
+  if( lch ) {
+    if( is_opnr(lch) ) {
+      for( uint8_t *ip=in; (ch=gch(ip))!=0; rch=ch );
+      if( lch == rch ) { sep = lch;  lch = gch(in); }
+    }
     while( (ch=gch(in)) != 0 ) {
-      lch = ch;  obp = out;
-      wnext(out, ch);
+      wnext(out, lch);  lch = ch;
     }
-    if( lch && is_opnr(lch) ) out = obp;
+    if( !sep ) wnext(out, lch);
   }
   *out = 0;
 }
 
+int brkput = 0;
+
 // converts c++ string to c string text
 static void xlat3(const char *cp, uint8_t *out)
 {
@@ -141,6 +144,11 @@ static void xlat3(const char *cp, uint8_t *out)
     }
     wnext(out,'\\');
     wnext(out, ch);
+    if( brkput && ch == 'n' && *bp ) {
+      wnext(out, '\"');
+      wnext(out, '\n');
+      wnext(out, '\"');
+    }
   }
   wnext(out, '\"');
   wnext(out, 0);
@@ -161,7 +169,7 @@ static void xlat4(const char *cp, uint8_t *out)
     case '\r':  ch = 'r';  break;
     case '\t':  ch = 't';  break;
     case '\v':  ch = 'v';  break;
-    case '\"': wnext(out,ch); // fall thru
+    case '\"': break;
     default: wnext(out,ch);  continue;
     }
     wnext(out,'\\');
@@ -206,7 +214,9 @@ static inline int bputs(uint8_t *bp, FILE *fp)
   if( !fp ) return 0;
   fputs((const char*)bp, fp);
   fputc('\n',fp);
-  return 1;
+  int n = 1;
+  while( *bp ) if( *bp++ == '\n' ) ++n;
+  return n;
 }
 static inline int bput(uint8_t *bp, FILE *fp)
 {
@@ -215,6 +225,8 @@ static inline int bput(uint8_t *bp, FILE *fp)
   return 1;
 }
 
+static bool goog = false;
+static bool nocmts = false;
 
 static inline bool is_nlin(unsigned ch, uint8_t *bp)
 {
@@ -320,13 +332,14 @@ static bool chkfmt(int no, uint8_t *ap, uint8_t *bp, uint8_t *cp)
   uint8_t *bep = bp;
   unsigned bpr = 0, bch = wnext(bp);
   for( ; bch!=0; bch=wnext(bp) ) {
-    if( is_opnr(bch) ) ++n;
+    if( goog && is_opnr(bch) ) ++n;
     bep = bp;  bpr = bch;
   }
+
   // trim solitary opnrs on ends b
-  if( n != 1 || !is_opnr(bpr) ) bep = bp;
+  if( goog && ( n != 1 || !is_opnr(bpr) ) ) bep = bp;
   bp = bsp;  bch = wnext(bp);
-  if( n == 1 && is_opnr(bch) ) bch = wnext(bp);
+  if( goog && ( n == 1 && is_opnr(bch) ) ) bch = wnext(bp);
 
   unsigned apr = 0, ach = wnext(ap);
   apr = bpr = 0;
@@ -337,40 +350,50 @@ static bool chkfmt(int no, uint8_t *ap, uint8_t *bp, uint8_t *cp)
     }
     // move to % on b
     while( bch != 0 && !is_per(bch) ) {
-      if( is_nlin(bch, bp) ) {
-        bch = '\n';  bp += 3;
-      }
-      else if( is_ccln(bch, bp) ) {
-        wnext(cp, bch=':');  bp += 3;
-      }
-      else if( is_quot(bch, bp) ) {
-        bch = '\"';  bp += 3;
-      }
-      else if( is_colon(bch) ) {
-        bch = ':';
+      if( goog ) { // google xlat recoginizers
+        if( is_nlin(bch, bp) ) {
+          bch = '\n';  bp += 3;
+        }
+        else if( is_ccln(bch, bp) ) {
+          wnext(cp, bch=':');  bp += 3;
+        }
+        else if( is_quot(bch, bp) ) {
+          bch = '\"';  bp += 3;
+        }
+        else if( is_colon(bch) ) {
+          bch = ':';
+        }
       }
       wnext(cp,bch);  bpr = bch;
       bch = bp >= bep ? 0 : wnext(bp);
     }
     if( !ach || !bch ) break;
+    if( !*ap && !*bp ) break;
     // if % on a and % on b and is fmt_spec
     if( is_per(ach) && is_per(bch) && (n=fmt_spec(ap)) > 0 ) {
-      if( apr != bpr ) wnext(cp,apr);
+      if( apr && apr != bpr ) wnext(cp,apr);
       wnext(cp,ach);  apr = ach;  ach = wnext(ap);
       // copy format data from a
       while( ach != 0 && --n >= 0 ) {
         wnext(cp, ach);  apr = ach;  ach = wnext(ap);
       }
       bpr = bch;  bch = bp >= bep ? 0 : wnext(bp);
-      // skip format data from b (ignore case)
-      while( bch != 0 && ((bpr ^ apr) & ~('a'-'A')) ) {
+      if( apr == '%' && bch == '%' ) {
+        // copy %% format data from b
         bpr = bch;
         bch = bp >= bep ? 0 : wnext(bp);
       }
-      // hit eol and didn't find end of spec on b
-      if( !bch && !((bpr ^ apr) & ~('a'-'A')) ) {
-        fprintf(stderr, "line %d: missed spec: %s\n", no, (char*)asp);
-        ret = false;
+      else {
+        // skip format data from b (ignore case)
+        while( bch != 0 && ((bpr ^ apr) & ~('a'-'A')) ) {
+          bpr = bch;
+          bch = bp >= bep ? 0 : wnext(bp);
+        }
+        // hit eol and didn't find end of spec on b
+        if( !bch && ((bpr ^ apr) & ~('a'-'A')) != 0 ) {
+          fprintf(stderr, "line %d: missed spec: %s\n", no, (char*)asp);
+          ret = false;
+        }
       }
     }
     else {
@@ -437,7 +460,8 @@ void scan_po(FILE *ifp, FILE *ofp)
 
   while( bgets(ibfr, sizeof(ibfr), ifp) ) {
     if( !prefix_is(ibfr, "msgid ") ) {
-      bputs(ibfr, ofp);  ++no;
+      if( nocmts && ibfr[0] == '#' ) continue;
+      no += bputs(ibfr, ofp);
       continue;
     }
     uint8_t str[MX_STR]; xlat2(&ibfr[6], str);
@@ -446,10 +470,10 @@ void scan_po(FILE *ifp, FILE *ofp)
       fprintf(stderr, "file truncated line %d: %s", no, ibfr);
       exit(1);
     }
-    bputs(ibfr, ofp);  ++no;
+    no += bputs(ibfr, ofp);
    
     while( tbfr[0] == '"' ) {
-      bputs(tbfr, ofp);  ++no;
+      no += bputs(tbfr, ofp);
       xlat2(&tbfr[0], str);  key.append((const char*)str);
       if( !bgets(tbfr, sizeof(tbfr), ifp) ) {
         fprintf(stderr, "file truncated line %d: %s", no, ibfr);
@@ -472,26 +496,26 @@ void scan_po(FILE *ifp, FILE *ofp)
     if( it == trans.end() || it->first.compare(key) ) {
       fprintf(stderr, "no trans line %d: %s\n", no, ibfr);
       xlat3(key.c_str(), &tbfr[7]);
-      bputs(tbfr, ofp);  ++no;
-      bputs((uint8_t*)"#msgstr \"\"", ofp); ++no;
+      //no += bputs(tbfr, ofp);
+      no += bputs((uint8_t*)"msgstr \"\"", ofp);
     }
-    else if( !it->second.ok ) {
+    else if( 0 && !it->second.ok ) {
       fprintf(stderr, "bad fmt line %d: %s\n", no, ibfr);
       xlat3(it->first.c_str(), &tbfr[7]);
-      bputs(tbfr, ofp);  ++no;
+      no += bputs(tbfr, ofp);
       xlat3(it->second.c_str(), str);
       bput((uint8_t*)"#msgstr ", ofp);
-      bputs(str, ofp);  ++no;
+      no += bputs(str, ofp);
     }
     else {
       xlat3(it->second.c_str(), &tbfr[7]);
-      bputs(tbfr, ofp);  ++no;
+      no += bputs(tbfr, ofp);
     }
   }
   if( ifp != stdin ) fclose(ifp);
 }
 
-void list_po(FILE *ifp, FILE *ofp)
+void list_po(FILE *ifp, FILE *ofp, int xeqx = 0, int nnul = 0)
 {
   int no = 0;
   int dup = 0, nul = 0;
@@ -528,8 +552,15 @@ void list_po(FILE *ifp, FILE *ofp)
       xlat2(&tbfr[0], str);  txt.append((const char*)str);
       ++no;
     }
-    if( !txt.size() ) { ++nul; continue; }
-    if( !key.compare(txt) ) { ++dup; continue; }
+    if( nnul && !txt.size() ) {
+      ++nul;
+      if( nnul > 0 ) continue;
+    }
+    else if( xeqx && !key.compare(txt) ) {
+       ++dup;
+       if( xeqx > 0 ) continue;
+    }
+    else if( nnul < 0 || xeqx < 0 ) continue;
     xlat4(key.c_str(), str);
     fprintf(ofp, "%s,", (char *)str);
     xlat4(txt.c_str(), str);
@@ -540,11 +571,13 @@ void list_po(FILE *ifp, FILE *ofp)
 
 static void usage(const char *av0)
 {
-  printf("test csv    %s  csv < data.csv\n",av0);
-  printf("test po     %s   po < data.po\n",av0);
-  printf("get strings %s  key < xgettext.po\n",av0);
-  printf("gen xlation %s xlat < xgettext.po xlat.csv\n",av0);
-  printf("gen xlation %s xlat < xgettext.po text,xlat ...\n",av0);
+  printf("list csv    %s csv < data.csv > data.po\n",av0);
+  printf("list po     %s po < data.po > data.csv\n",av0);
+  printf("list po     %s dups < data.po\n",av0);
+  printf("list po     %s nodups < data.po\n",av0);
+  printf("get strings %s key  < xgettext.po\n",av0);
+  printf("gen xlation %s xlat   xgettext.po xlat.csv\n",av0);
+  printf("gen xlation %s xlat - text,xlat ... < xgettext.po\n",av0);
   exit(1);
 }
 
@@ -552,15 +585,31 @@ int main(int ac, char **av)
 {
   if( ac == 1 ) usage(av[0]);
 
+  // if to rework google xlat output
+  if( getenv("GOOG") ) goog = true;
+  if( getenv("NOCMTS") ) nocmts = true;
+
   if( !strcmp(av[1],"csv") ) {  // test csv
     load(stdin, 0);
     for( Trans::iterator it = trans.begin(); it!=trans.end(); ++it ) {
-      uint8_t str[MX_STR];  xlat3(it->second.c_str(), str);
-      printf("key = \"%s\", val = %s\n", it->first.c_str(), (char *)str);
+      uint8_t str1[MX_STR];  xlat3(it->first.c_str(), str1);
+      printf("msgid %s\n", (char *)str1);
+      uint8_t str2[MX_STR];  xlat3(it->second.c_str(), str2);
+      printf("msgstr %s\n\n", (char *)str2);
     }
     return 0;
   }
 
+  if( !strcmp(av[1],"dups") ) {  // test po
+    list_po(stdin, stdout, -1, -1);
+    return 0;
+  }
+
+  if( !strcmp(av[1],"nodups") ) {  // test po
+    list_po(stdin, stdout, 1, 1);
+    return 0;
+  }
+
   if( !strcmp(av[1],"po") ) {  // test po
     list_po(stdin, stdout);
     return 0;
@@ -583,6 +632,7 @@ int main(int ac, char **av)
     return 1;
   }
 
+  brkput = 1;
   for( int i=3; i<ac; ++i ) {  // create trans mapping
     fprintf(stderr,"*** load %s\n", av[i]);
     char fn[MX_STR*2];