Back to index

courier  0.68.2
log.c
Go to the documentation of this file.
00001 /* Log file output.
00002    Copyright (C) 2003, 2005, 2009 Free Software Foundation, Inc.
00003 
00004    This program is free software; you can redistribute it and/or modify it
00005    under the terms of the GNU Library General Public License as published
00006    by the Free Software Foundation; either version 2, or (at your option)
00007    any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public
00015    License along with this program; if not, write to the Free Software
00016    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00017    USA.  */
00018 
00019 /* Written by Bruno Haible <bruno@clisp.org>.  */
00020 
00021 #ifdef HAVE_CONFIG_H
00022 # include <config.h>
00023 #endif
00024 
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 
00029 /* Handle multi-threaded applications.  */
00030 #ifdef _LIBC
00031 # include <bits/libc-lock.h>
00032 #else
00033 # include "lock.h"
00034 #endif
00035 
00036 /* Separator between msgctxt and msgid in .mo files.  */
00037 #define MSGCTXT_SEPARATOR '\004'  /* EOT */
00038 
00039 /* Print an ASCII string with quotes and escape sequences where needed.  */
00040 static void
00041 print_escaped (FILE *stream, const char *str, const char *str_end)
00042 {
00043   putc ('"', stream);
00044   for (; str != str_end; str++)
00045     if (*str == '\n')
00046       {
00047         fputs ("\\n\"", stream);
00048         if (str + 1 == str_end)
00049           return;
00050         fputs ("\n\"", stream);
00051       }
00052     else
00053       {
00054         if (*str == '"' || *str == '\\')
00055           putc ('\\', stream);
00056         putc (*str, stream);
00057       }
00058   putc ('"', stream);
00059 }
00060 
00061 static char *last_logfilename = NULL;
00062 static FILE *last_logfile = NULL;
00063 __libc_lock_define_initialized (static, lock)
00064 
00065 static inline void
00066 _nl_log_untranslated_locked (const char *logfilename, const char *domainname,
00067                              const char *msgid1, const char *msgid2, int plural)
00068 {
00069   FILE *logfile;
00070   const char *separator;
00071 
00072   /* Can we reuse the last opened logfile?  */
00073   if (last_logfilename == NULL || strcmp (logfilename, last_logfilename) != 0)
00074     {
00075       /* Close the last used logfile.  */
00076       if (last_logfilename != NULL)
00077         {
00078           if (last_logfile != NULL)
00079             {
00080               fclose (last_logfile);
00081               last_logfile = NULL;
00082             }
00083           free (last_logfilename);
00084           last_logfilename = NULL;
00085         }
00086       /* Open the logfile.  */
00087       last_logfilename = (char *) malloc (strlen (logfilename) + 1);
00088       if (last_logfilename == NULL)
00089         return;
00090       strcpy (last_logfilename, logfilename);
00091       last_logfile = fopen (logfilename, "a");
00092       if (last_logfile == NULL)
00093         return;
00094     }
00095   logfile = last_logfile;
00096 
00097   fprintf (logfile, "domain ");
00098   print_escaped (logfile, domainname, domainname + strlen (domainname));
00099   separator = strchr (msgid1, MSGCTXT_SEPARATOR);
00100   if (separator != NULL)
00101     {
00102       /* The part before the MSGCTXT_SEPARATOR is the msgctxt.  */
00103       fprintf (logfile, "\nmsgctxt ");
00104       print_escaped (logfile, msgid1, separator);
00105       msgid1 = separator + 1;
00106     }
00107   fprintf (logfile, "\nmsgid ");
00108   print_escaped (logfile, msgid1, msgid1 + strlen (msgid1));
00109   if (plural)
00110     {
00111       fprintf (logfile, "\nmsgid_plural ");
00112       print_escaped (logfile, msgid2, msgid2 + strlen (msgid2));
00113       fprintf (logfile, "\nmsgstr[0] \"\"\n");
00114     }
00115   else
00116     fprintf (logfile, "\nmsgstr \"\"\n");
00117   putc ('\n', logfile);
00118 }
00119 
00120 /* Add to the log file an entry denoting a failed translation.  */
00121 void
00122 _nl_log_untranslated (const char *logfilename, const char *domainname,
00123                       const char *msgid1, const char *msgid2, int plural)
00124 {
00125   __libc_lock_lock (lock);
00126   _nl_log_untranslated_locked (logfilename, domainname, msgid1, msgid2, plural);
00127   __libc_lock_unlock (lock);
00128 }