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

txtfiletools.c

/* txtfiletools.c
 * Part of ziproxy package
 *
 * Copyright (c)2005-2008 Daniel Mealha Cabrita
 *
 * Released subject to GNU General Public License v2 or later version.
 *
 * Misc tools when dealing with text files.
 */

#include <stdio.h>
#include <stdlib.h>

/* converts CRLF and CR to that standard and closes dst with '\0' 
 * it also replaces '\0' in the middle of the text with spaces
 * return: size of resulting text (may be <= srclen because of CR suppression, for example) */
/* *dst may be the same pointer as *src, but the buffer must be at least srclen+1 */
int fix_linebreaks_qp (const unsigned char *src, int srclen, unsigned char *dst)
{
      const unsigned char     *rpos = src;
      unsigned char           *wpos = dst;
      unsigned char           prevchar = '\0';
      unsigned char           curchar;
      int   prevchar_was_cr_or_lf = 0;
      int   curchar_is_cr_or_lf;
      int   count = srclen;
      int   dstlen = 0;

      while (count--) {
            curchar = *(rpos++);
            curchar_is_cr_or_lf = 0;
            if ((curchar == '\n') || (curchar == '\r')) {
                  curchar_is_cr_or_lf = 1;
                  if ((!prevchar_was_cr_or_lf) || ((prevchar_was_cr_or_lf) && (prevchar == curchar))) {
                        *(wpos++) = '\n';
                        dstlen++;
                  }
            } else if (curchar != '\0') {
                  *(wpos++) = curchar;
                  dstlen++;
            } else {
                  *(wpos++) = ' ';
                  dstlen++;
            }
            prevchar_was_cr_or_lf = curchar_is_cr_or_lf;
            prevchar = curchar;
      }
      *wpos = '\0';

      return (dstlen);
}

/* returns null if unsuccessful
 * pointed buffer must be freed after usage
 * returns file size into *filesize, if filesize != NULL
 * the returned data consists of the file data itself, with an
 * appended '\0' to it (thus, it's a valid C string) */
/* FIXME: this routine does not expect IO errors */
char *load_textfile_to_memory (const char *given_filename)
{
      int my_filesize;
      char *my_buff;
      FILE *my_file;

      if ((my_file = fopen (given_filename, "rb")) != NULL) {
            /* determine file size */
            fseek (my_file, 0, SEEK_END);
            my_filesize = ftell (my_file);
            fseek (my_file, 0, SEEK_SET);

            if ((my_buff = malloc (my_filesize + 1)) != NULL) {
                  fread (my_buff, my_filesize, 1, my_file);
                  fclose (my_file);
                  *(my_buff + my_filesize) = '\0';
                  return (my_buff);
            } else {
                  fclose (my_file);
            }
      }

      return(NULL);
}

/* equivalent to strlen, but instead of stopping at '\0', stops at <which_char> (or '\0') */
/* returns line len (including the trailing <which_char>) */
int get_line_len_char (const char *src, const char which_char)
{
      int linelen = 0;

      while ((*src != '\0') && (*src != which_char)) {
            src++;
            linelen++;
      }
      if (*src == which_char)
            linelen++;

      return (linelen);
}



/* equivalent to strlen, but instead of stopping at '\0', stops at '\n' (or '\0') */
/* returns line len (including the trailing '\n') */
/* TODO: reimplement reusing get_line_len_char() */
int get_line_len (const char *src)
{
      int linelen = 0;

      while ((*src != '\0') && (*src != '\n')) {
            src++;
            linelen++;
      }
      if (*src == '\n')
            linelen++;

      return (linelen);
}

/* remove comments and empty lines, leave only useful config data */
/* 'src' may be the same as 'dst' */
void remove_junk_data (const char *src, char *dst)
{
      int linelen, counter;
      int emptyline;
      int inside_grouping;
      const char *readpos, *readpos2;
      char *writepos, *writepos2;

      /* remove comments */
      readpos = src;
      writepos = dst;
      while ((linelen = get_line_len (readpos)) != 0) {
            counter = linelen;
            while (counter) {
                  if (*readpos == '#') {
                        /* ignore the rest of the line */
                        if (*(readpos + counter - 1) == '\n')
                              *(writepos++) = '\n';
                        readpos += counter;
                        counter = 0;
                  } else {
                        *(writepos++) = *(readpos++);
                        counter--;
                  }
            }
      }
      *writepos = '\0';
      
      /* remove empty lines (just spaces/tabs/etc or simply empty) */
      readpos = dst;
      writepos = dst;
      while ((linelen = get_line_len (readpos)) != 0) {
            counter = linelen;
            emptyline = 1;
            readpos2 = readpos;
            writepos2 = writepos;
            while (counter--) {
                  if ((*readpos2 > ' ') && (*readpos2 != '\n'))
                        emptyline = 0;
                  readpos2++;
            }

            if (emptyline == 0) {
                  counter = linelen;
                  while (counter--)
                        *(writepos++) = *(readpos++);
            } else {
                  readpos += linelen;
            }
      }
      *writepos = '\0';

      /* remove unneccessary spaces */
      readpos = dst;
      writepos = dst;
      while ((linelen = get_line_len (readpos)) != 0) {
            counter = linelen;
            while (counter) {
                  if ((*readpos <= ' ') && (*readpos != '\n')) {
                        readpos++;
                  } else if (*readpos == '\\') {
                        *(writepos++) = *(readpos++);
                        if (counter > 1) {
                              *(writepos++) = *(readpos++);
                              counter--;
                        }
                  } else {
                        *(writepos++) = *(readpos++);
                  }
                  counter--;
            }
      }
      *writepos = '\0';
}



Generated by  Doxygen 1.6.0   Back to index