Exemple #1
0
void cleanup() /* {{{ */
{
	/* function to run on termination */
	keybind *lastbind;

	/* free memory allocated normally */
	check_free(searchstring);
	free_tasks(head);
	check_free(cfg.sortmode);
	free(cfg.version);
	free(cfg.formats.task);
	free(cfg.formats.title);
	free(cfg.formats.view);
	free(active_filter);
	while (keybinds!=NULL)
	{
		lastbind = keybinds;
		keybinds = keybinds->next;
		check_free(lastbind->argstr);
		free(lastbind);
	}
	free_colors();
	free_prompts();
	free_formats();

	/* close open files */
	fflush(logfp);
	fclose(logfp);
} /* }}} */
int					/* O - Exit code */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int			i;		/* Looping var */
  cups_array_t		*po;		/* .po file */
  _cups_message_t	*msg;		/* Current message */
  cups_array_t		*idfmts,	/* Format strings in msgid */
			*strfmts;	/* Format strings in msgstr */
  char			*idfmt,		/* Current msgid format string */
			*strfmt;	/* Current msgstr format string */
  int			fmtidx;		/* Format index */
  int			status,		/* Exit status */
			pass,		/* Pass/fail status */
			untranslated;	/* Untranslated messages */
  char			idbuf[80],	/* Abbreviated msgid */
			strbuf[80];	/* Abbreviated msgstr */


  if (argc < 2)
  {
    puts("Usage: checkpo filename.po [... filenameN.po]");
    return (1);
  }

 /*
  * Check every .po file on the command-line...
  */

  for (i = 1, status = 0; i < argc; i ++)
  {
   /*
    * Use the CUPS .po loader to get the message strings...
    */

    if ((po = _cupsMessageLoad(argv[i], 1)) == NULL)
    {
      perror(argv[i]);
      return (1);
    }

    if (i > 1)
      putchar('\n');
    printf("%s: ", argv[i]);
    fflush(stdout);

   /*
    * Scan every message for a % string and then match them up with
    * the corresponding string in the translation...
    */

    pass         = 1;
    untranslated = 0;

    for (msg = (_cups_message_t *)cupsArrayFirst(po);
         msg;
	 msg = (_cups_message_t *)cupsArrayNext(po))
    {
     /*
      * Make sure filter message prefixes are not translated...
      */

      if (!strncmp(msg->id, "ALERT:", 6) || !strncmp(msg->id, "CRIT:", 5) ||
          !strncmp(msg->id, "DEBUG:", 6) || !strncmp(msg->id, "DEBUG2:", 7) ||
          !strncmp(msg->id, "EMERG:", 6) || !strncmp(msg->id, "ERROR:", 6) ||
          !strncmp(msg->id, "INFO:", 5) || !strncmp(msg->id, "NOTICE:", 7) ||
          !strncmp(msg->id, "WARNING:", 8))
      {
        if (pass)
	{
	  pass = 0;
	  puts("FAIL");
	}

	printf("    Bad prefix on filter message \"%s\"\n",
	       abbreviate(msg->id, idbuf, sizeof(idbuf)));
      }

      idfmt = msg->id + strlen(msg->id) - 1;
      if (idfmt >= msg->id && *idfmt == '\n')
      {
        if (pass)
	{
	  pass = 0;
	  puts("FAIL");
	}

	printf("    Trailing newline in message \"%s\"\n",
	       abbreviate(msg->id, idbuf, sizeof(idbuf)));
      }

      for (; idfmt >= msg->id; idfmt --)
        if (!isspace(*idfmt & 255))
	  break;

      if (idfmt >= msg->id && *idfmt == '!')
      {
        if (pass)
	{
	  pass = 0;
	  puts("FAIL");
	}

	printf("    Exclamation in message \"%s\"\n",
	       abbreviate(msg->id, idbuf, sizeof(idbuf)));
      }

      if ((idfmt - 2) >= msg->id && !strncmp(idfmt - 2, "...", 3))
      {
        if (pass)
	{
	  pass = 0;
	  puts("FAIL");
	}

	printf("    Ellipsis in message \"%s\"\n",
	       abbreviate(msg->id, idbuf, sizeof(idbuf)));
      }


      if (!msg->str || !msg->str[0])
      {
        untranslated ++;
	continue;
      }
      else if (strchr(msg->id, '%'))
      {
        idfmts  = collect_formats(msg->id);
	strfmts = collect_formats(msg->str);
	fmtidx  = 0;

        for (strfmt = (char *)cupsArrayFirst(strfmts);
	     strfmt;
	     strfmt = (char *)cupsArrayNext(strfmts))
	{
	  if (isdigit(strfmt[1] & 255) && strfmt[2] == '$')
	  {
	   /*
	    * Handle positioned format stuff...
	    */

            fmtidx = strfmt[1] - '1';
            strfmt += 3;
	    if ((idfmt = (char *)cupsArrayIndex(idfmts, fmtidx)) != NULL)
	      idfmt ++;
	  }
	  else
	  {
	   /*
	    * Compare against the current format...
	    */

	    idfmt = (char *)cupsArrayIndex(idfmts, fmtidx);
          }

	  fmtidx ++;

	  if (!idfmt || strcmp(strfmt, idfmt))
	    break;
	}

        if (cupsArrayCount(strfmts) != cupsArrayCount(idfmts) || strfmt)
	{
	  if (pass)
	  {
	    pass = 0;
	    puts("FAIL");
	  }

	  printf("    Bad translation string \"%s\"\n        for \"%s\"\n",
	         abbreviate(msg->str, strbuf, sizeof(strbuf)),
		 abbreviate(msg->id, idbuf, sizeof(idbuf)));
          fputs("    Translation formats:", stdout);
	  for (strfmt = (char *)cupsArrayFirst(strfmts);
	       strfmt;
	       strfmt = (char *)cupsArrayNext(strfmts))
	    printf(" %s", strfmt);
          fputs("\n    Original formats:", stdout);
	  for (idfmt = (char *)cupsArrayFirst(idfmts);
	       idfmt;
	       idfmt = (char *)cupsArrayNext(idfmts))
	    printf(" %s", idfmt);
          putchar('\n');
          putchar('\n');
	}

	free_formats(idfmts);
	free_formats(strfmts);
      }

     /*
      * Only allow \\, \n, \r, \t, \", and \### character escapes...
      */

      for (strfmt = msg->str; *strfmt; strfmt ++)
        if (*strfmt == '\\' &&
	    strfmt[1] != '\\' && strfmt[1] != 'n' && strfmt[1] != 'r' &&
	    strfmt[1] != 't' && strfmt[1] != '\"' && !isdigit(strfmt[1] & 255))
	{
	  if (pass)
	  {
	    pass = 0;
	    puts("FAIL");
	  }

	  printf("    Bad escape \\%c in filter message \"%s\"\n"
	         "      for \"%s\"\n", strfmt[1],
		 abbreviate(msg->str, strbuf, sizeof(strbuf)),
		 abbreviate(msg->id, idbuf, sizeof(idbuf)));
          break;
        }
    }

    if (pass)
    {
      if ((untranslated * 10) >= cupsArrayCount(po) &&
          strcmp(argv[i], "cups.pot"))
      {
       /*
        * Only allow 10% of messages to be untranslated before we fail...
	*/

        pass = 0;
        puts("FAIL");
	printf("    Too many untranslated messages (%d of %d)\n",
	       untranslated, cupsArrayCount(po));
      }
      else if (untranslated > 0)
        printf("PASS (%d of %d untranslated)\n", untranslated,
	       cupsArrayCount(po));
      else
        puts("PASS");
    }

    if (!pass)
      status = 1;

    _cupsMessageFree(po);
  }

  return (status);
}