Logo Search packages:      
Sourcecode: udo version File versions  Download package

str.c

/*    ############################################################
      # @(#) str.c
      # @(#)
      # @(#) Copyright (c) 1995-2001 by Dirk Hagedorn
      # @(#) Dirk Hagedorn (udo@dirk-hagedorn.de)
      #
      # This program is free software; you can redistribute it and/or
      # modify it under the terms of the GNU General Public License
      # as published by the Free Software Foundation; either version 2
      # of the License, or (at your option) any later version.
      # 
      # This program is distributed in the hope that it will be useful,
      # but WITHOUT ANY WARRANTY; without even the implied warranty of
      # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      # GNU General Public License for more details.
      # 
      # You should have received a copy of the GNU General Public License
      # along with this program; if not, write to the Free Software
      # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
      ############################################################      */

#ifndef ID_STR_C
#define     ID_STR_C
const char *id_str_c= "@(#) str.c       10.03.1997";
#endif

#include "import.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "portab.h"

#include "export.h"
#include "str.h"
#include "version.h"

#include "msg.h"

/*
      #################################################################
      #
      # strcat und strcpy Wrapper, die Puffergrenzen checken können
      #
      #################################################################
*/

GLOBAL char *um_strcpy(char *dest, const char *src, size_t max, const char *place)
{
      char errbuf[120];
      size_t slen; /* Temporäre Variable, für die Länge von src */
      
      slen=(size_t)strlen(src); /* Stringlänge bestimmen */
      if (((size_t)slen+1)<max) /* Testen obs  */
      {
            return strcpy(dest, src);
      }
      else
      {
            dest[0]=EOS;
            sprintf(errbuf, "um_strcpy: buffer overrun prevented: %s: %d>%d", place, slen+1, max);
            loglnposprintf ("Warning", errbuf);
            return dest;
      }
}

GLOBAL char *um_strncpy(char *dest, const char *src, size_t n, size_t max, const char *place)
{
      char errbuf[120];
      if ((n+1)<max)
      {
            return strncpy(dest, src, n);
      }
      else
      {
            dest[0]=EOS;
            sprintf(errbuf, "um_strncpy: buffer overrun prevented: %s: %d>%d", place, n+1, max);
            loglnposprintf ("Warning", errbuf);
            return dest;
      }
}

GLOBAL char *um_strcat(char *dest, const char *src, size_t max, const char *place)
{
      char errbuf[120];
      size_t dlen, slen;

      dlen=(size_t)strlen(dest);
      slen=(size_t)strlen(src);
      
      if ((dlen+slen+1)<max)
      {
            return strcat(dest, src);
      }
      else
      {
            dest[0]=EOS;
            sprintf(errbuf, "um_strcat: buffer overrun prevented: %s: %d>%d", place, dlen+slen+1, max);
            loglnposprintf ("Warning", errbuf);
            return dest;
      }
}

GLOBAL char *um_strncat(char *dest, const char *src, size_t n, size_t max, const char *place)
{
      char errbuf[120];
      size_t dlen;

      dlen=strlen(dest);
      if ((dlen+n+1)<max)
      {
            return strncat(dest, src, n);
      }
      else
      {
            dest[0]=EOS;
            sprintf(errbuf, "um_strncat: buffer overrun prevented: %s: %d>%d", place, dlen+n+1, max);
            loglnposprintf("Warning", errbuf);
            return dest;
      }
}

/*    ############################################################
      #
      # Anhaengen von Strings und Zeichen
      #
      ############################################################      */
/*    ----------------------------------------------------------------------
      chrcat()
      Aufgabe: Anhaengen eines Zeichens an einen String
      ----------------------------------------------------------------------  */
GLOBAL char *chrcat (char *dest, const char c)
{
      char one[2]={0,0};

      one[0]= c;
      return(strcat(dest, one));
}     /* chrcat */



/*    ############################################################
      #
      # Einfuegen von Strings
      #
      ############################################################      */
/*    ------------------------------------------------------------
      strinsert() fuegt am Anfang von <s> den String <ins> ein
      ->    string: String, in dem eingefuegt werden soll
            insert:     einzufuegender String
      <-    Zeiger auf <string>
      ------------------------------------------------------------      */
GLOBAL char *strinsert ( char *string, const char *insert)
{
      char  *start;
      size_t      sl, il;
      
      if ( insert[0]=='\0' )
      {     return string;
      }
      
      sl= strlen(string);
      il= strlen(insert);

      /* Platz schaffen fuer neues und dorthin kopieren */
      start= string;
      memmove(string+il, string, sl+1);
      memcpy(start, insert, il);
      
      return string;
}     /*strinsert*/



/*    ############################################################
      #
      # Ersetzen von einzelnen Zeichen
      #
      ############################################################      */
/*    ------------------------------------------------------------
      replace_char() ersetzt in <string> das erste Zeichen von
      <replace> durch das erste Zeichen von <by>
      ------------------------------------------------------------      */
GLOBAL void replace_char ( char *string, const char *replace, const char *by )
{
      char *ptr;
      
      ptr= string;

      while (*ptr!=EOS)
      {
            if (*ptr==*replace)
            {     *ptr= *by;
            }
            ptr++;
      }

}     /* replace_char */



/*    ############################################################
      #
      # Ersetzen von Strings
      #
      ############################################################      */

/*    ------------------------------------------------------------
      replace_once() ersetzt in <s> einmal <rep> durch <by>
      ->    source: String, in dem ersetzt werden soll
            rep:  zu ersetzender String
            by:         neuer String
      <-    1:    String wurde ersetzt
            0:    String nicht gefunden
      ------------------------------------------------------------      */
GLOBAL int replace_once ( char *source, const char *replace, const char *by)
{
      char  *found;
      size_t      rlen, blen, flen;
      
      if ( source[0]=='\0' )        return 0;
      if ( replace[0]=='\0' )       return 0;
      
      if ( (found= strstr(source, replace))==NULL )   return 0;

      rlen=strlen(replace);
      flen= strlen(found);

      /* Zu Ersetzendes entfernen */
      memmove(found, found+rlen, flen-rlen+1);

      /* Platz schaffen fuer neues und dorthin kopieren */
      if ( by[0]!=EOS )
      {     blen= strlen(by);
            flen= strlen(found);
            memmove(found+blen, found, flen+1);
            memcpy(found, by, blen);
      }
      
      return 1;
}     /*replace_once*/


/*    ------------------------------------------------------------
      replace_last() ersetzt in <s> das letzte <rep> durch <by>
      ------------------------------------------------------------      */
GLOBAL int replace_last ( char *source, const char *replace, const char *by)
{
      char *found, *look, *last;

      if ( source[0]=='\0' )        return 0;
      if ( replace[0]=='\0' )       return 0;
      
      look= source;
      last= NULL;

      while ( (found= strstr(look, replace))!=NULL )
      {     look= found+1;
            last= found;
      }

      if (last!=NULL)
      {     return ( replace_once(last, replace, by) );
      }
      
      return 0;
}     /* replace_last */



/*    ------------------------------------------------------------
      replace_all() ersetzt in <s> alle <rep> durch <by>
      ------------------------------------------------------------      */
GLOBAL int replace_all ( char *source, const char *replace, const char *by)
{
      char  *found;
      size_t      rlen, blen, flen, i;
      
      if ( source[0]=='\0' )        return 0;
      if ( replace[0]=='\0' )       return 0;

      if ( (found= strstr(source, replace))==NULL )   return 0;

      rlen=strlen(replace);
      blen= strlen(by);

      if (rlen==blen)
      {
            while ( found!=NULL )
            {
                  for (i=0; i<blen; i++)
                  {     found[i]= by[i];
                  }
                  found= strstr(found+blen, replace);
            }
            return 1;
      }

      while ( found!=NULL )
      {
            flen= strlen(found);

            /* Zu Ersetzendes entfernen */
            memmove(found, found+rlen, flen-rlen+1);
      
            /* Platz schaffen fuer neues und dorthin kopieren */
            if ( by[0]!=EOS )
            {     flen= strlen(found);
                  memmove(found+blen, found, flen+1);
                  memcpy(found, by, blen);
                  found= strstr(found+blen, replace);
            }
            else
            {     found= strstr(found, replace);
            }
      }
      
      return 1;
}     /*replace_all*/



/*    ############################################################
      #
      # Ersetzen von Strings (schnelle Variante) r6pl2
      #
      ############################################################      */

/*    ------------------------------------------------------------
      qreplace_once() ersetzt in <s> einmal <rep> durch <by>
      Im Gegensatz zu replace_one() sind die Laengen der Strings
      bekannt (kein strlen() noetig). Dadurch   ist diese Routine
      schneller als replace_one(): "q" steht fuer "quick"
      ->    source:           String, in dem ersetzt werden soll
            replace:    zu ersetzender String
            rlen:       strlen(replace)
            by:               neuer String
            blen:       strlen(by)
      <-    1:    String wurde ersetzt
            0:    String nicht gefunden
      ------------------------------------------------------------      */
GLOBAL int qreplace_once (    char *source,
                                          const char *replace,
                                          const size_t rlen,
                                          const char *by,
                                          const size_t blen
                                    )
{
      char  *found;
      size_t      flen;

#if CHECK_REPLACE_LEN
      if (rlen!=strlen(replace))
      {     fprintf(stdout, "Fehler in qreplace_once:\n");
            fprintf(stdout, "rlen= %d\n", rlen);
            fprintf(stdout, "strlen(%s)= %d\n", replace, strlen(replace));
      }
      if (blen!=strlen(by))
      {     fprintf(stdout, "Fehler in qreplace_once:\n");
            fprintf(stdout, "blen= %d\n", blen);
            fprintf(stdout, "strlen(%s)= %d\n", by, strlen(by));
      }
#endif
      
      if ( source[0]=='\0' )        return 0;
      if ( replace[0]=='\0' )       return 0;

      if ( (found= strstr(source, replace))==NULL )   return 0;

      flen= strlen(found);

      /* Zu Ersetzendes entfernen */
      memmove(found, found+rlen, flen-rlen+1);

      /* Platz schaffen fuer neues und dorthin kopieren */
      if ( by[0]!=EOS )
      {     flen= strlen(found);
            memmove(found+blen, found, flen+1);
            memcpy(found, by, blen);
      }
      
      return 1;
}     /* qreplace_once */


/*    ------------------------------------------------------------
      qreplace_last() ersetzt in <s> das letzte <rep> durch <by>
      ------------------------------------------------------------      */
GLOBAL int qreplace_last (    char *source,
                                          const char *replace,
                                          const size_t rlen,
                                          const char *by,
                                          const size_t blen
                                    )
{
      char *found, *look, *last;

#if CHECK_REPLACE_LEN
      if (rlen!=strlen(replace))
      {     fprintf(stdout, "Fehler in qreplace_last:\n");
            fprintf(stdout, "rlen= %d\n", rlen);
            fprintf(stdout, "strlen(%s)= %d\n", replace, strlen(replace));
      }
      if (blen!=strlen(by))
      {     fprintf(stdout, "Fehler in qreplace_last:\n");
            fprintf(stdout, "blen= %d\n", blen);
            fprintf(stdout, "strlen(%s)= %d\n", by, strlen(by));
      }
#endif

      if ( source[0]=='\0' )        return 0;
      if ( replace[0]=='\0' )       return 0;
      
      look= source;
      last= NULL;

      while ( (found= strstr(look, replace))!=NULL )
      {     look= found+1;
            last= found;
      }

      if (last!=NULL)
      {     return ( qreplace_once(last, replace, rlen, by, blen) );
      }
      
      return 0;
}     /* qreplace_last */



/*    ------------------------------------------------------------
      qreplace_all() ersetzt in <s> alle <rep> durch <by>
      ------------------------------------------------------------      */
GLOBAL int qreplace_all (     char *source,
                                          const char *replace,
                                          const size_t rlen,
                                          const char *by,
                                          const size_t blen
                                    )
{
      char  *found;
      size_t      flen, i;

#if CHECK_REPLACE_LEN
      if (rlen!=strlen(replace))
      {     fprintf(stdout, "Fehler in qreplace_all:\n");
            fprintf(stdout, "rlen= %d\n", rlen);
            fprintf(stdout, "strlen(%s)= %d\n", replace, strlen(replace));
      }
      if (blen!=strlen(by))
      {     fprintf(stdout, "Fehler in qreplace_all:\n");
            fprintf(stdout, "blen= %d\n", blen);
            fprintf(stdout, "strlen(%s)= %d\n", by, strlen(by));
      }
#endif
      
      if ( source[0]=='\0' )        return 0;
      if ( replace[0]=='\0' )       return 0;

      if ( (found= strstr(source, replace))==NULL )   return 0;

      if (rlen==blen)
      {
            while ( found!=NULL )
            {
                  for (i=0; i<blen; i++)
                  {     found[i]= by[i];
                  }
                  found= strstr(found+blen, replace);
            }
            return 1;
      }

      while ( found!=NULL )
      {     flen= strlen(found);

            /* Zu Ersetzendes entfernen */
            memmove(found, found+rlen, flen-rlen+1);
      
            /* Platz schaffen fuer neues und dorthin kopieren */
            if ( by[0]!=EOS )
            {     flen= strlen(found);
                  memmove(found+blen, found, flen+1);
                  memcpy(found, by, blen);
                  found= strstr(found+blen, replace);
            }
            else
            {     found= strstr(found, replace);
            }
            
      }

      return 1;
}     /* qreplace_all */





/*    ############################################################
      #
      # Loeschen von Strings
      #
      ############################################################      */
GLOBAL int delete_once ( char *source, const char *to_delete )
{
      return(replace_once (source, to_delete, ""));
}

GLOBAL int delete_last ( char *source, const char *to_delete )
{
      return(replace_last (source, to_delete, ""));
}

GLOBAL int delete_all ( char *source, const char *to_delete )
{
      return(replace_all (source, to_delete, ""));
}


GLOBAL int qdelete_once ( char *source, const char *to_delete, const size_t dlen )
{
      return ( qreplace_once (source, to_delete, dlen, "", 0) );
}

GLOBAL int qdelete_last ( char *source, const char *to_delete, const size_t dlen )
{
      return ( qreplace_last (source, to_delete, dlen, "", 0) );
}

GLOBAL int qdelete_all ( char *source, const char *to_delete, const size_t dlen )
{
      return ( qreplace_all (source, to_delete, dlen, "", 0) );
}



/*    ------------------------------------------------------------
      del_right_spaces() entfernt Leerzeichen am Ende
      ------------------------------------------------------------      */
GLOBAL void del_right_spaces ( char *s )
{
      size_t      sl;
      
      sl= strlen(s);

      while (     (sl>0) && (s[sl-1]==' ') )
      {     s[sl-1]= EOS;
            sl--;
      }

}     /* del_right_spaces */



/*    ------------------------------------------------------------
      del_whitespaces() entfernt Leerzeichen und Tabs am Anfang
      und Ende des uebergebenen Strings.
      ------------------------------------------------------------      */
GLOBAL void del_whitespaces ( char *s)
{
      size_t      sl;
      
      /* Neue Methode: schneller */
      
      char *p1st = s;
      
      while (*p1st != EOS && (*p1st == ' ' || *p1st == '\t') )
      {     ++p1st;
      }

      sl = strlen(p1st);
      
      if (*p1st != EOS && s != p1st)
      {     
            memmove(s, p1st, sl+1);
      }
      
      /* Rechts TAB's und Leerzeichen entfernen */
      if (sl > 0)
      {
            p1st = s + sl - 1;
            while (*p1st == ' ' || *p1st == '\t')
                  --p1st;
            p1st[1] = EOS;
      }
}     /*del_whitespaces*/


/*    --------------------------------------------------------------
      get_brackets_ptr()
      Ermittelt aus einem String wie "!raw [ stg, tex ] foo bar"
      oder "!docinfo [author] Dirk Hagedorn" den Zeiger auf das
      erste Zeichen hinter der ersten [ und die Anzahl der Zeichen,
      die bis zur ersten ] folgen.
      ->    s:          Der zu untersuchende String
      <-    cont: Zeiger auf das erste Zeichen des Inhalts
            data: Zeiger auf das erste Zeichen der Daten
            0:          fehlerhafte Syntax (keine [ und ] gefunden)
            sonst:      Laenge des Inhaltes
      --------------------------------------------------------------    */
GLOBAL size_t get_brackets_ptr ( char *s, char **cont, char **data )
{
      char *ptr;
      size_t len;
      
      ptr= s;
      *cont= NULL;
      *data= NULL;
      len= 0;
      
      while (*ptr!=EOS)
      {
            if (*ptr=='[')
            {     *cont= ptr+1;
            }
            
            if (*ptr==']')
            {     if (*cont!=NULL)
                  {     *data= ptr+1;
                        len= ptr - *cont;
                  }
                  return len;
            }
            
            ptr++;
      }

      return 0;   
      
}     /* get_brackets_ptr */


/* New since r6pl15 [NHz] */
/*    --------------------------------------------------------------
      get_two_brackets_ptr()
      Ermittelt aus einem String wie "!doclayout [ ps, rtf ] [paper] foo bar"
      die Zeiger auf die ersten Zeichen hinter den ersten [ und die
      Anzahl der Zeichen, die bis zur ersten ] folgen.
      ->    s:          Der zu untersuchende String
      <-    cont_format:      Zeiger auf das erste Zeichen der Formate
          cont_content: Zeiger auf das erste Zeichen des Inhalts
            data: Zeiger auf das erste Zeichen der Daten
            0:          fehlerhafte Syntax (keine [ und ] gefunden)
            sonst:      Laenge des Inhaltes
      --------------------------------------------------------------    */
GLOBAL struct size_brackets get_two_brackets_ptr ( char *s, char **cont_format, char **cont_content, char **data )
{
      char *ptr;
      struct size_brackets len;
      BOOLEAN firstend;
      
      ptr= s;
      *cont_format= NULL;
      *cont_content= NULL;
      *data= NULL;
      len.format= 0;
      len.content= 0;
      
      firstend = FALSE;

      while (*ptr!=EOS)
      {
            if ((*ptr=='[') && (!firstend))
            {     *cont_format= ptr+1;
            }
            
            else if ((*ptr==']') && (!firstend))
            {     firstend = TRUE;
                  len.format= ptr - *cont_format;
            }
            
            else if ((*ptr=='[') && (firstend))
            {     *cont_content= ptr+1;
            }

            else if ((*ptr==']') && (firstend))
            {     if (*cont_content!=NULL)
                  {     *data= ptr+1;
                        len.content= ptr - *cont_content;
                  }
                  return len;
            }
            
            ptr++;
      }

      return len; 
      
}     /* get_two_brackets_ptr */


/*    --------------------------------------------------------------
      get_8bit_ptr() ermittelt die Position des ersten 8-Bit-Chars
      eines Strings.
      ->    s:    Zeiger auf den String
      <-    Zeiger auf das erste 8-Bit-Zeichen bzw. NULL, wenn kein
            8-Bit-Zeichen enthalten ist.
      --------------------------------------------------------------    */
GLOBAL char *get_8bit_ptr ( char *s )
{
      char *ptr;
      
      ptr= s;
      
      while ( *ptr!=EOS )
      {     if ( (UCHAR) *ptr > 127 )
            {     return ptr;
            }
            ptr++;
      }
      
      return NULL;
}


/*    --------------------------------------------------------------
      get_section_ptr() ermittelt die Position des ersten
      Paragraphen-Zeichens eines Strings, dass bei DOS und OS/2
      unter \025 zu finden ist
      ->    s:    Zeiger auf den String
      <-    Zeiger auf das Zeichen bzw. NULL, wenn nicht enthalten
      --------------------------------------------------------------    */
GLOBAL char *get_section_ptr ( char *s )
{
      char *ptr;
      
      ptr= s;
      
      while ( *ptr!=EOS )
      {     if ( (UCHAR) *ptr == '\025' )
            {     return ptr;
            }
            ptr++;
      }
      
      return NULL;
}     /* get_section_ptr */


/*    --------------------------------------------------------------
      get_1stchar_ptr() ermittelt die Position des ersten Zeichens,
      das sich von ' ' und '\t' unterscheidet.
      ->    s:    Zeiger auf den String
      <-    Zeiger auf das erste Zeichen oder NULL, wenn der String
            leer oder nur Blanks und/der TABs enthaelt
      --------------------------------------------------------------    */
GLOBAL char *get_1stchar_ptr ( char *s )
{
      char *ptr;
      
      ptr= s;
      
      while ( *ptr!=EOS )
      {     if ( *ptr!=' ' && *ptr!='\t' )
            {     return ptr;
            }
            ptr++;
      }
      
      return NULL;
}



/*    ############################################################
      #
      # Umwandlungsroutinen
      #
      ############################################################      */

/*    ----------------------------------------------
      TABs in Leerzeichen umwandeln und dabei die
      Tabposition beachten
      ----------------------------------------------  */
GLOBAL void tabs2spaces (char *s, const int tw)
{
      char n[1024], one[2]={0, 0};
      size_t i, nl;

      /* r6pl2: Wenn !bDocTabwidth==0 dann nicht ersetzen! */
      if (tw==0)
      {     return;
      }

      n[0]= EOS;
      nl= 0;
      
      for (i=0; i<strlen(s); i++)
      {     if (s[i]=='\t')
            {     do
                  {     strcat(n, " ");
                        nl++;
                  }     while ( (nl % tw)!=0 );
            }
            else
            {     one[0]= s[i];
                  strcat(n, one);
                  nl++;
            }
      }

      strcpy(s, n);     

}     /* tabs2spaces */



/*    ----------------------------------------------
      Dezimalzahlen in roemische Zahlen umwandeln
      I =    1     IV      =    4
      V =    5     IX      =    9
      X =   10     XL      =   40
      L =   50     XC      =   90
      C =  100     CD      =  400
      D =  500     CM      =  900
      M = 1000     MCMXCVI = 1996
      ----------------------------------------------  */

GLOBAL char *itoroman ( int value, char *string )
{
      int   t, c, d, o, i;
      
      static const char *cent[]=    {     "", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"  };
      static const char *deci[]=    {     "", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"  };
      static const char *ones[]=    {     "", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"  };

      string[0]= '\0';

      if (value<=0)
      {     return(string);
      }
      
      t= value/1000;
      c= (value-t*1000)/100;
      d= (value-t*1000-c*100)/10;
      o= (value-t*1000-c*100-d*10);
      
      
      for (i=0; i<t; i++)     strcat(string, "m") ;

      strcat(string, cent[c]);      
      strcat(string, deci[d]);      
      strcat(string, ones[o]);      
      
      return(string);
}     /* itoroman */


/*    ----------------------------------------------
      String in Grossbuchstaben umwandeln
      ----------------------------------------------  */
GLOBAL void my_strupr ( char *string )
{
#if HAVE_STRUPR
      strupr(string);
#else
      size_t i;
      if (string[0]==EOS)
      {     return;
      }
      
      for (i=0; i<strlen(string); i++)
      {     if ( string[i]>='a' && string[i]<='z' )
            {
                  string[i] = (char)toupper(string[i]);
            }
      }
#endif
}     /* my_strupr */

/*    ----------------------------------------------
      String in Kleinbuchstaben umwandeln
      ----------------------------------------------  */
GLOBAL void my_strlwr ( char *string )
{
#if HAVE_STRLWR
      strlwr(string);
#else
      size_t i;
      if (string[0]==EOS)
      {     return;
      }
      
      for (i=0; i<strlen(string); i++)
      {     if ( string[i]>='A' && string[i]<='Z' )
            {
                  string[i] = (char)tolower(string[i]);
            }
      }
#endif
}     /* my_strlwr */


/*    ----------------------------------------------
      Strings caseinsensitiv vergleichen
      ----------------------------------------------  */
GLOBAL int my_stricmp ( const char *s1, const char *s2 )
{

#if HAVE_STRICMP
        return stricmp(s1, s2);
#elif HAVE_STRCASECMP
        return strcasecmp(s1, s2);
#else
        return strcmp(s1, s2);
#endif

}     /* my_stricmp */

/*    ----------------------------------------------
      Strings caseinsensitiv vergleichen
      max. n Zeichen
      ----------------------------------------------  */
GLOBAL int my_strnicmp ( const char *s1, const char *s2, size_t len )
{

#if HAVE_STRNICMP
      return strnicmp(s1, s2, len);
#else
      return strncmp(s1, s2, len);
#endif

}     /* my_stricmp */

/*    ############################################################
      # str.c
      ############################################################      */


Generated by  Doxygen 1.6.0   Back to index