/* 
   elmo - ELectronic Mail Operator

   Copyright (C) 2002, 2003, 2004 rzyjontko

   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; version 2.

   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.  

   ----------------------------------------------------------------------

   some miscelaneous functions used only for checking purposes
   
*/
/****************************************************************************
 *    IMPLEMENTATION HEADERS
 ****************************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#include <ctype.h>

#include "xmalloc.h"
#include "error.h"
#include "ecurses.h"

/****************************************************************************
 *    IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE DATA
 ****************************************************************************/
/****************************************************************************
 *    INTERFACE DATA
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
 ****************************************************************************/
/****************************************************************************
 *    IMPLEMENTATION PRIVATE FUNCTIONS
 ****************************************************************************/

static char *
get_key (int key)
{
        static char buf[7];
  
        buf[0] = key;
        buf[1] = '\0';

        if (key < 255 && isalnum (key))
                return buf;

        if (key < 255 && strchr ("<>!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?~`", key))
                return buf;

        switch (key){
                case '\t':
                        return "<tab>";

                case '\b':
                case KEY_BACKSPACE:
                        return "<backspace>";

                case 27:
                        return "<esc>";

                case KEY_UP:
                        return "<up>";

                case KEY_DOWN:
                        return "<down>";

                case KEY_LEFT:
                        return "<left>";

                case KEY_RIGHT:
                        return "<right>";

                case KEY_PPAGE:
                        return "<pagedown>";

                case KEY_NPAGE:
                        return "<pageup>";

                case KEY_DC:
                        return "<delete>";

                case KEY_IC:
                        return "<insert>";

                case '\r':
                        return "<enter>";

                case KEY_HOME:
                        return "<home>";

                case KEY_END:
                        return "<end>";

                case ' ':
                        return "<space>";
        }

        if (key < 'z' - 'a' + 1){
                sprintf (buf, "\\C-%c", key + 'a' - 1);
                return buf;
        }
  
        if (key >= KEY_F (1) && key <= KEY_F (12)){
                sprintf (buf, "<f%d>", key - KEY_F (1) + 1);
                return buf;
        }

        return NULL;
}

/****************************************************************************
 *    INTERFACE FUNCTIONS
 ****************************************************************************/

#ifndef HAVE_STPCPY

char *
stpcpy (char *dest, const char *src)
{
        int len = strlen (src);

        memcpy (dest, src, len + 1);
        return dest + len;
}

#endif


char *
human_size (int size)
{
        static char hsize[40];

        if (size >= 1024 * 1024 * 900){
                snprintf (hsize, sizeof (hsize), "%d.%dG",
                          size / (1024 * 1024 * 1024),
                          size % (1024 * 1024 * 1024) * 10 / (1024 * 1024 * 1024));
        }
        else if (size >= 1024 * 900){
                snprintf (hsize, sizeof (hsize), "%d.%dM", size / (1024 * 1024),
                          size % (1024 * 1024) * 10 / (1024 * 1024));
        }
        else if (size >= 900){
                snprintf (hsize, sizeof (hsize), "%d.%dK", size / 1024,
                          size % 1024 * 10 / 1024);
        }
        else {
                snprintf (hsize, sizeof (hsize), "%d", size);
        }
        return hsize;
}


char *
date_string (const char *format, time_t tm)
{
        static char  time_s[80];
        char        *result;
        int          len;
        struct tm   *loctime;

        loctime = localtime (&tm);
        len     = strftime (time_s, sizeof (time_s), format, loctime);
        result  = xmalloc (6 + len + 1);
        memcpy (result, time_s, len + 1);

        return result;
}


int
misc_logarithm (int n)
{
        int i = 0;

        while (n){
                n >>= 1;
                i++;
        }
        if (i == 0)
                i = 1;
        return i;
}


int
misc_regex (const char *re, const char *text, regmatch_t *matches)
{
        int     ret;
        regex_t compiled;
  
        ret = regcomp (&compiled, re, REG_ICASE | REG_EXTENDED | REG_NEWLINE);

        if (ret){
                error_regex (ret, &compiled, re);
                regfree (&compiled);
                return 0;
        }

        ret = regexec (&compiled, text, 1, matches, 0);

        if (ret && ret != REG_NOMATCH){
                error_regex (ret, &compiled, re);
        }
        regfree (&compiled);
        return ! ret;
}


char *
key2string (int key, int meta)
{
        static char  result[40];
        char        *s_key;

        s_key = get_key (key);

        if (s_key == NULL)
                return NULL;

        if (! meta)
                return s_key;

        sprintf (result, "\\M-%s", s_key);
        return result;
}



char *
misc_re_from_str (const char *str)
{
        int   len    = strlen (str);
        char *re     = xmalloc (2 * len + 1);
        char *re_ptr = re;
        
        while (*str){
                switch (*str){
                        case '.': case '*': case '+': case '-': case '[':
                        case ']': case '(': case ')': case '{': case '}':
                        case '\\':
                                re_ptr[0] = '\\';
                                re_ptr[1] = *str;
                                re_ptr   += 2;
                                break;

                        default:
                                *re_ptr = *str;
                                re_ptr++;
                                break;
                }
                str++;
        }
        *re_ptr = '\0';
        return re;
}


/****************************************************************************
 *    INTERFACE CLASS BODIES
 ****************************************************************************/
/****************************************************************************
 *
 *    END MODULE misc.c
 *
 ****************************************************************************/


syntax highlighted by Code2HTML, v. 0.9.1