/*
This source file is part of Scol
For the latest info, see http://www.scolring.org

Copyright (c) 2010 Stephane Bisaro, aka Iri <iri@irizone.net>

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser 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, or go to
http://www.gnu.org/copyleft/lesser.txt

For others informations, please contact us from http://www.scolring.org/
*/


#include "lib_string.h"

char * replaceChar (char *s, char cin, char cout)
{
    unsigned int i = 0;

    for (i = 0; i < strlen (s); i++)
    {
        if (s[i] == cin)
            s[i] = cout;
    }
    return s;
}


void lib_string_removePrefix (char **str, const char * prefix)
{
    if (!(strncasecmp (*str, prefix, strlen (prefix))))
        strncpy (*str, *str+strlen (prefix), strlen (*str));
    return;
}

void lib_string_addPrefix (char **str, const char * prefix)
{
    if (strncasecmp (*str, prefix, strlen (prefix)))
    {
        int len, lenprefix;
        char * newstr;

        len = strlen (*str);
        lenprefix = strlen (prefix);
        newstr = (char *) malloc (sizeof (char) * (len + lenprefix + 1));
        *str = (char *) realloc (*str, sizeof (char) * (len + lenprefix + 1));
        snprintf (newstr, len+lenprefix+1, "%s%s", prefix, *str);
        newstr[len+lenprefix] = '\0';
        strncpy (*str, newstr, len+lenprefix);
        (*str)[len+lenprefix] = '\0';
        free (newstr);
        return;
    }
    return;
}

void lib_string_addSuffixChar (char ** str, const char suffix)
{
    int len;
    len = strlen (*str);

    if ((*str)[len-1] != suffix)   /* add a last slash if needed */
    {
        char * tmp;

        tmp = (char *) malloc (sizeof (char) * len+2);
        snprintf (tmp, len+2, "%s/", *str);
        *str = (char *) realloc (*str, sizeof (char *) * len + 2);
        strncpy (*str, tmp, len+2);
        (*str)[len+2] = '\0';
        free (tmp);
    }
    return;
}

/* From a source by Nicolas Joseph, 12 / 2010
 Return the first position of a substring in a string */
int lib_string_indexstr (const char *cs, const char *ct)
{
    int index = -1;
    char *ptr_pos = NULL;

    if (cs && ct)
    {
        ptr_pos = strstr (cs, ct);
        if (ptr_pos)
            index = ptr_pos - cs;
    }
    return index;
}

/* Return the first position of a char in a string */
int lib_string_indexchar (const char *cs, const char ct)
{
    int index = -1;
    char *ptr_pos = NULL;

    if (cs && ct)
    {
        ptr_pos = strchr (cs, ct);
        if (ptr_pos)
            index = ptr_pos - cs;
    }
    return index;
}

int lib_string_isLastChar (const char *s, const char c)
{
    char *tmp = NULL;

    tmp = strrchr (s, c);
    if (strlen (tmp) <= 1)
        return 0;
    return 1;
}

void lib_string_getListeFromStringWithDelimiter (struct LibString_List *list, char *first, const char *sep)
{
    int len;
    char *p;
    struct LibString_List *l;

    p = strtok (first, sep);
    if (p == NULL)
        return;

    len = strlen (p);
    l = (struct LibString_List *) malloc (sizeof (struct LibString_List));
    l->word = (char *) malloc (sizeof (char) * (len + 1));
    strcpy (l->word, p);
    l->word[len] = '\0';
    l->pNext = list;
    list = l;

    while (l != NULL)
    {
        p = strtok (NULL, sep);
        if (p != NULL)
        {
            len = strlen (p);
            l = (struct LibString_List *) malloc (sizeof (struct LibString_List));
            l->word = (char *) malloc (sizeof (char) * (len + 1));
            strcpy (l->word, p);
            l->word[len] = '\0';
            l->pNext = list;
            list = l;
        }
        else
            l = NULL;
    }
    return;
}

void lib_string_freeListeFromStringWithDelimiter (struct LibString_List *list)
{
    while (list != NULL)
    {
        free (list->word);
        list = list->pNext;
    }
    free (list);
    return;
}





/* scan a directory and theses subdirectories to search a file. Return 0 if found, out is its path */
int lib_string_scan_dir_file2 (char *path, const char *name, char **out)
{
    DIR *d, *sd;
    struct dirent *entry;
#if !((defined _WIN32) || (defined __WIN32__))
    struct stat *s = NULL;
#endif
    char dir[SIZESIGN][SIZESIGN];
    char buffer[SIZESIGN];
    int i, k, ndir = 0;

#if !((defined _WIN32) || (defined __WIN32__))
    s = malloc (sizeof (struct stat));
#endif
    strncpy (dir[ndir++], path, SIZESIGN-1);
    d = opendir (dir[0]);
    if (d == NULL)
    {
        MMechostr (MSKDEBUG, "lib_string_scan_dir_file error : unable to open the initial directory\n");
        return 1;
    }
    while ((entry = readdir (d)))
    {
        if ((!strcmp (entry->d_name, ".")) || (!strcmp (entry->d_name, "..")))
        {

        }
        else
        {
            snprintf (buffer, SIZESIGN-1, "%s%c%s", path, SEP, entry->d_name);
            /* now, case of the symbolic link */
#if ((defined _WIN32) || (defined __WIN32__))
            k = GetFileAttributes (buffer);
            if (k == INVALID_FILE_ATTRIBUTES)
                MMechostr (MSKDEBUG, "lib_string_scan_dir_file error : unable to retreive the file/directory attributes : %s   %d  %s\n", buffer, errno, strerror (errno));
            else if (!(k & FILE_ATTRIBUTE_REPARSE_POINT))   /* not a symbolic link */
#else
            stat (buffer, s);
            if (!(s->st_mode & S_IFLNK))   /* not a symbolic link */
#endif
            {
                sd = opendir (buffer);
                if (sd != NULL)
                {
                    k = snprintf (dir[ndir++], SIZESIGN-1, "%s", buffer);
                    if ((k < 0) || (k >= SIZESIGN))
                    {
                        dir[ndir][0] = '\0';
                        ndir--;
                        MMechostr (MSKDEBUG, "lib_string_scan_dir_file error : result is too large\n");
                    }
                }
                else
                {
                    if (!strcmp (entry->d_name, name))
                    {
                        k = snprintf (*out, SIZESIGN-1, "%s%c%s", path, SEP, entry->d_name);
                        return ((k < 0) || (k >= SIZESIGN)) ? 2 : 0;
                    }
                }
            }
        }
    }
#if !((defined _WIN32) || (defined __WIN32__))
    free (s);
#endif
    for (i = 1; i < ndir; i++)
        if (lib_string_scan_dir_file2 (dir[i], name, out) == 0) return 0;

    return 1;
}




/* function by Allan Darling */
int nisalnum(char *s, int n) {

   for (; *s && n; s++, n--)

      if (!isalnum(*s))
         return (0);

   return (1);

} /* end nisalnum */

