Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
pango-utils.c File Reference
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include "pango-utils.h"

Go to the source code of this file.

Defines

#define flockfile(f)   (void)1
#define funlockfile(f)   (void)1
#define getc_unlocked(f)   getc(f)
#define UTF8_COMPUTE(Char, Mask, Len)
#define UTF8_LENGTH(Char)
#define UTF8_GET(Result, Chars, Count, Mask, Len)
#define UNICODE_VALID(Char)

Functions

char * pangolite_trim_string (const char *str)
 pangolite_trim_string: : a string
char ** pangolite_split_file_list (const char *str)
 pangolite_split_file_list: : a comma separated list of filenames
gint pangolite_read_line (FILE *stream, GString *str)
 pangolite_read_line: : a stdio stream : #GString buffer into which to write the result
gboolean pangolite_skip_space (const char **pos)
 pangolite_skip_space: : in/out string position
gboolean pangolite_scan_word (const char **pos, GString *out)
 pangolite_scan_word: : in/out string position : a #GString into which to write the result
gboolean pangolite_scan_string (const char **pos, GString *out)
 pangolite_scan_string: : in/out string position : a #GString into which to write the result
gboolean pangolite_scan_int (const char **pos, int *out)
static void read_config_file (const char *filename, gboolean enoent_error)
static void read_config ()
char * pangolite_config_key_get (const char *key)
 pangolite_config_key_get: : Key to look up, in the form "SECTION/KEY".
G_CONST_RETURN char * pangolite_get_sysconf_subdirectory (void)
G_CONST_RETURN char * pangolite_get_lib_subdirectory (void)
gunichar g_utf8_get_char (const gchar *p)
 g_utf8_get_char: : a pointer to unicode character encoded as UTF-8

Variables

static GHashTable * config_hash = NULL

Define Documentation

#define flockfile (   f)    (void)1

Definition at line 53 of file pango-utils.c.

#define funlockfile (   f)    (void)1

Definition at line 54 of file pango-utils.c.

#define getc_unlocked (   f)    getc(f)

Definition at line 55 of file pango-utils.c.

Value:
((Char) < 0x110000 && ((Char) < 0xD800 || (Char) >= 0xE000) && \
   (Char) != 0xFFFE && (Char) != 0xFFFF)

Definition at line 110 of file pango-utils.c.

#define UTF8_COMPUTE (   Char,
  Mask,
  Len 
)
Value:
if (Char < 128)      { \
    Len = 1; \
    Mask = 0x7f;     \
  }    \
  else if ((Char & 0xe0) == 0xc0)  { \
    Len = 2;  \
    Mask = 0x1f;     \
  }    \
  else if ((Char & 0xf0) == 0xe0)  { \
    Len = 3; \
    Mask = 0x0f; \
  }    \
  else if ((Char & 0xf8) == 0xf0)  { \
    Len = 4; \
    Mask = 0x07; \
  }    \
  else if ((Char & 0xfc) == 0xf8)  { \
    Len = 5; \
    Mask = 0x03; \
  }    \
  else if ((Char & 0xfe) == 0xfc)  { \
    Len = 6; \
    Mask = 0x01; \
  }    \
  else \
   Len = -1;

Definition at line 64 of file pango-utils.c.

#define UTF8_GET (   Result,
  Chars,
  Count,
  Mask,
  Len 
)
Value:
(Result) = (Chars)[0] & (Mask);    \
  for ((Count) = 1; (Count) < (Len); ++(Count))  { \
    if (((Chars)[(Count)] & 0xc0) != 0x80) { \
            (Result) = -1; \
            break; \
         }    \
    (Result) <<= 6;  \
    (Result) |= ((Chars)[(Count)] & 0x3f); \
  }

Definition at line 99 of file pango-utils.c.

Value:
((Char) < 0x80 ? 1 : \
   ((Char) < 0x800 ? 2 :  \
    ((Char) < 0x10000 ? 3 : \
     ((Char) < 0x200000 ? 4 : \
      ((Char) < 0x4000000 ? 5 : 6)))))

Definition at line 92 of file pango-utils.c.


Function Documentation

gunichar g_utf8_get_char ( const gchar *  p)

g_utf8_get_char: : a pointer to unicode character encoded as UTF-8

Convert a sequence of bytes encoded as UTF-8 to a unicode character.

Return value: the resulting character or (gunichar)-1 if does not point to a valid UTF-8 encoded unicode character

Definition at line 733 of file pango-utils.c.

{
  int i, mask = 0, len;
  gunichar result;
  unsigned char c = (unsigned char) *p;

  UTF8_COMPUTE (c, mask, len);
  if (len == -1)
    return (gunichar)-1;
  UTF8_GET (result, p, i, mask, len);

  return result;
}

Here is the caller graph for this function:

char* pangolite_config_key_get ( const char *  key)

pangolite_config_key_get: : Key to look up, in the form "SECTION/KEY".

Look up a key in the pangolite config database (pseudo-win.ini style, read from $sysconfdir/pangolite/pangoliterc, ~/.pangoliterc, and getenv (PANGO_RC_FILE).)

Return value: the value, if found, otherwise NULL. The value is a newly-allocated string and must be freed with g_free().

Definition at line 673 of file pango-utils.c.

{
  g_return_val_if_fail (key != NULL, NULL);
  
  read_config ();

  return g_strdup (g_hash_table_lookup (config_hash, key));
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 703 of file pango-utils.c.

{
#ifdef G_OS_WIN32
  static gchar *result = NULL;

  if (result == NULL)
    result = g_win32_get_package_installation_subdirectory
      ("pangolite", g_strdup_printf ("pangolite-%s.dll", PANGO_VERSION), "lib\\pangolite");

  return result;
  // Open to any other way of doing this
  // Bottomline : need to provide path to pangolite libraries
  // Currently set to dist/bin - Open to other locations
#else
  char *tmp = getenv("MOZILLA_FIVE_HOME");
  return tmp;
  /*  return "/home/prabhath/PROJ/opt/lib"; */
#endif
}

Here is the caller graph for this function:

Definition at line 683 of file pango-utils.c.

{
#ifdef G_OS_WIN32
  static gchar *result = NULL;

  if (result == NULL)
    result = g_win32_get_package_installation_subdirectory
      ("pangolite", g_strdup_printf ("pangolite-%s.dll", PANGO_VERSION), "etc\\pangolite");

  return result;
  // Am open to any other way of doing this
  // Bottomline : need to provide path to pango.modules
  /* Currently set to dist/bin - Am open to other location */
#else
  char *tmp = getenv("MOZILLA_FIVE_HOME");
  return tmp;
#endif
}

Here is the caller graph for this function:

gint pangolite_read_line ( FILE stream,
GString *  str 
)

pangolite_read_line: : a stdio stream : #GString buffer into which to write the result

Read an entire line from a file into a buffer. Lines may be delimited with '
', '', '
', or '
'. The delimiter is not written into the buffer. Text after a '#' character is treated as a comment and skipped. '\' can be used to escape a # character. '\' proceding a line delimiter combines adjacent lines. A '\' proceding any other character is ignored and written into the output buffer unmodified.

Return value: 0 if the stream was already at an EOF character, otherwise the number of lines read (this is useful for maintaining a line number counter which doesn't combine lines with )

Definition at line 215 of file pango-utils.c.

{
  gboolean quoted = FALSE;
  gboolean comment = FALSE;
  int n_read = 0;
  int lines = 1;
  
  flockfile (stream);

  g_string_truncate (str, 0);
  
  while (1)
    {
      int c;
      
      c = getc_unlocked (stream);

      if (c == EOF)
       {
         if (quoted)
           g_string_append_c (str, '\\');
         
         goto done;
       }
      else
       n_read++;

      if (quoted)
       {
         quoted = FALSE;
         
         switch (c)
           {
           case '#':
             g_string_append_c (str, '#');
             break;
           case '\r':
           case '\n':
             {
              int next_c = getc_unlocked (stream);

              if (!(next_c == EOF ||
                    (c == '\r' && next_c == '\n') ||
                    (c == '\n' && next_c == '\r')))
                ungetc (next_c, stream);

              lines++;
              
              break;
             }
           default:
             g_string_append_c (str, '\\');            
             g_string_append_c (str, c);
           }
       }
      else
       {
         switch (c)
           {
           case '#':
             comment = TRUE;
             break;
           case '\\':
             if (!comment)
              quoted = TRUE;
             break;
           case '\n':
             {
              int next_c = getc_unlocked (stream);

              if (!(c == EOF ||
                    (c == '\r' && next_c == '\n') ||
                    (c == '\n' && next_c == '\r')))
                ungetc (next_c, stream);

              goto done;
             }
           default:
             if (!comment)
              g_string_append_c (str, c);
           }
       }
    }

 done:

  funlockfile (stream);

  return (n_read > 0) ? lines : 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

gboolean pangolite_scan_int ( const char **  pos,
int out 
)

Definition at line 459 of file pango-utils.c.

{
  int i = 0;
  char buf[32];
  const char *p = *pos;

  while (isspace (*p))
    p++;
  
  if (*p < '0' || *p > '9')
    return FALSE;

  while ((*p >= '0') && (*p <= '9') && i < sizeof(buf))
    {
      buf[i] = *p;
      i++;
      p++;
    }

  if (i == sizeof(buf))
    return FALSE;
  else
    buf[i] = '\0';

  *out = atoi (buf);

  return TRUE;
}
gboolean pangolite_scan_string ( const char **  pos,
GString *  out 
)

pangolite_scan_string: : in/out string position : a #GString into which to write the result

Scan a string into a #GString buffer. The string may either be a sequence of non-white-space characters, or a quoted string with '"'. Instead a quoted string, '"' represents a literal quote. Leading white space outside of quotes is skipped.

Return value: FALSE if a parse error occured.

Definition at line 383 of file pango-utils.c.

{
  const char *p = *pos;
  
  while (isspace (*p))
    p++;

  if (!*p)
    return FALSE;
  else if (*p == '"')
    {
      gboolean quoted = FALSE;
      g_string_truncate (out, 0);

      p++;

      while (TRUE)
       {
         if (quoted)
           {
             int c = *p;
             
             switch (c)
              {
              case '\0':
                return FALSE;
              case 'n':
                c = '\n';
                break;
              case 't':
                c = '\t';
                break;
              }
             
             quoted = FALSE;
             g_string_append_c (out, c);
           }
         else
           {
             switch (*p)
              {
              case '\0':
                return FALSE;
              case '\\':
                quoted = TRUE;
                break;
              case '"':
                p++;
                goto done;
              default:
                g_string_append_c (out, *p);
                break;
              }
           }
         p++;
       }
    done:
      ;
    }
  else
    {
      g_string_truncate (out, 0);

      while (*p && !isspace (*p))
       {
         g_string_append_c (out, *p);
         p++;
       }
    }

  *pos = p;

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

gboolean pangolite_scan_word ( const char **  pos,
GString *  out 
)

pangolite_scan_word: : in/out string position : a #GString into which to write the result

Scan a word into a #GString buffer. A word consists of [A-Za-z_] followed by zero or more [A-Za-z_0-9] Leading white space is skipped.

Return value: FALSE if a parse error occured.

Definition at line 340 of file pango-utils.c.

{
  const char *p = *pos;

  while (isspace (*p))
    p++;
  
  if (!((*p >= 'A' && *p <= 'Z') ||
       (*p >= 'a' && *p <= 'z') ||
       *p == '_'))
    return FALSE;

  g_string_truncate (out, 0);
  g_string_append_c (out, *p);
  p++;

  while ((*p >= 'A' && *p <= 'Z') ||
        (*p >= 'a' && *p <= 'z') ||
        (*p >= '0' && *p <= '9') ||
        *p == '_')
    {
      g_string_append_c (out, *p);
      p++;
    }

  *pos = p;

  return TRUE;
}

Here is the caller graph for this function:

gboolean pangolite_skip_space ( const char **  pos)

pangolite_skip_space: : in/out string position

Skips 0 or more characters of white space.

Return value: FALSE if skipping the white space leaves the position at a '\0' character.

Definition at line 316 of file pango-utils.c.

{
  const char *p = *pos;
  
  while (isspace (*p))
    p++;

  *pos = p;

  return !(*p == '\0');
}

Here is the caller graph for this function:

char** pangolite_split_file_list ( const char *  str)

pangolite_split_file_list: : a comma separated list of filenames

Split a G_SEARCHPATH_SEPARATOR-separated list of files, stripping white space and subsituting ~/ with $HOME/

Return value: a list of strings to be freed with g_strfreev()

Definition at line 149 of file pango-utils.c.

{
  int i = 0;
  int j;
  char **files;

  files = g_strsplit (str, G_SEARCHPATH_SEPARATOR_S, -1);

  while (files[i])
    {
      char *file = pangolite_trim_string (files[i]);

      /* If the resulting file is empty, skip it */
      if (file[0] == '\0')
       {
         g_free(file);
         g_free (files[i]);
         
         for (j = i + 1; files[j]; j++)
           files[j - 1] = files[j];
         
         files[j - 1] = NULL;

         continue;
       }
#ifndef G_OS_WIN32
      /* '~' is a quite normal and common character in file names on
       * Windows, especially in the 8.3 versions of long file names, which
       * still occur and then. Also, few Windows user are aware of the
       * Unix shell convention that '~' stands for the home directory,
       * even if they happen to have a home directory.
       */
      if (file[0] == '~' && file[1] == G_DIR_SEPARATOR)
       {
         char *tmp = g_strconcat (g_get_home_dir(), file + 1, NULL);
         g_free (file);
         file = tmp;
       }
#endif
      g_free (files[i]);
      files[i] = file;
       
      i++;
    }

  return files;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* pangolite_trim_string ( const char *  str)

pangolite_trim_string: : a string

Trim leading and trailing whitespace from a string.

Return value: A newly allocated string that must be freed with g_free()

Definition at line 123 of file pango-utils.c.

{
  int len;

  g_return_val_if_fail (str != NULL, NULL);
  
  while (*str && isspace (*str))
    str++;

  len = strlen (str);
  while (len > 0 && isspace (str[len-1]))
    len--;

  return g_strndup (str, len);
}

Here is the caller graph for this function:

static void read_config ( ) [static]

Definition at line 631 of file pango-utils.c.

{
  if (!config_hash)
    {
      char *filename;
      char *home;
      
      config_hash = g_hash_table_new (g_str_hash, g_str_equal);
      filename = g_strconcat (pangolite_get_sysconf_subdirectory (),
                           G_DIR_SEPARATOR_S "pangoliterc",
                           NULL);
      read_config_file (filename, FALSE);
      g_free (filename);

      home = g_get_home_dir ();
      if (home && *home)
       {
         filename = g_strconcat (home,
                              G_DIR_SEPARATOR_S ".pangoliterc",
                              NULL);
         read_config_file (filename, FALSE);
         g_free (filename);
       }

      filename = g_getenv ("PANGO_RC_FILE");
      if (filename)
       read_config_file (filename, TRUE);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void read_config_file ( const char *  filename,
gboolean  enoent_error 
) [static]

Definition at line 491 of file pango-utils.c.

{
  FILE *file;
    
  GString *line_buffer;
  GString *tmp_buffer1;
  GString *tmp_buffer2;
  char *errstring = NULL;
  const char *pos;
  char *section = NULL;
  int line = 0;

  file = fopen (filename, "r");
  if (!file)
    {
      if (errno != ENOENT || enoent_error)
       fprintf (stderr, "Pangolite:%s: Error opening config file: %s\n",
               filename, g_strerror (errno));
      return;
    }
  
  line_buffer = g_string_new (NULL);
  tmp_buffer1 = g_string_new (NULL);
  tmp_buffer2 = g_string_new (NULL);

  while (pangolite_read_line (file, line_buffer))
    {
      line++;

      pos = line_buffer->str;
      if (!pangolite_skip_space (&pos))
       continue;

      if (*pos == '[')      /* Section */
       {
         pos++;
         if (!pangolite_skip_space (&pos) ||
             !pangolite_scan_word (&pos, tmp_buffer1) ||
             !pangolite_skip_space (&pos) ||
             *(pos++) != ']' ||
             pangolite_skip_space (&pos))
           {
             errstring = g_strdup ("Error parsing [SECTION] declaration");
             goto error;
           }

         section = g_strdup (tmp_buffer1->str);
       }
      else                  /* Key */
       {
         gboolean empty = FALSE;
         gboolean append = FALSE;
         char *k, *v;

         if (!section)
           {
             errstring = g_strdup ("A [SECTION] declaration must occur first");
             goto error;
           }

         if (!pangolite_scan_word (&pos, tmp_buffer1) ||
             !pangolite_skip_space (&pos))
           {
             errstring = g_strdup ("Line is not of the form KEY=VALUE or KEY+=VALUE");
             goto error;
           }
         if (*pos == '+')
           {
             append = TRUE;
             pos++;
           }

         if (*(pos++) != '=')
           {
             errstring = g_strdup ("Line is not of the form KEY=VALUE or KEY+=VALUE");
             goto error;
           }
           
         if (!pangolite_skip_space (&pos))
           {
             empty = TRUE;
           }
         else
           {
             if (!pangolite_scan_string (&pos, tmp_buffer2))
              {
                errstring = g_strdup ("Error parsing value string");
                goto error;
              }
             if (pangolite_skip_space (&pos))
              {
                errstring = g_strdup ("Junk after value string");
                goto error;
              }
           }

         g_string_prepend_c (tmp_buffer1, '/');
         g_string_prepend (tmp_buffer1, section);

         /* Remove any existing values */
         if (g_hash_table_lookup_extended (config_hash, tmp_buffer1->str,
                                       (gpointer *)&k, (gpointer *)&v))
           {
             g_free (k);
             if (append)
              {
                g_string_prepend (tmp_buffer2, v);
                g_free (v);
              }
           }
             
         if (!empty)
           {
             g_hash_table_insert (config_hash,
                               g_strdup (tmp_buffer1->str),
                               g_strdup (tmp_buffer2->str));
           }
       }
    }
      
  if (ferror (file))
    errstring = g_strdup ("g_strerror(errno)");
  
 error:

  if (errstring)
    {
      fprintf (stderr, "Pangolite:%s:%d: %s\n", filename, line, errstring);
      g_free (errstring);
    }
      
  g_free (section);
  g_string_free (line_buffer, TRUE);
  g_string_free (tmp_buffer1, TRUE);
  g_string_free (tmp_buffer2, TRUE);

  fclose (file);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

GHashTable* config_hash = NULL [static]

Definition at line 488 of file pango-utils.c.