/*
 * $Id$
 *
 * New generation of string handling functions safe from a memory management point of view 
 * Developped by Andree Leidenfrost
 */

#include <stdio.h>
#include <string.h>
#include <time.h>

#include "mr_mem.h"
 
/**
 * Safe alternative to standard function strok()
 * Build a partition name from a drive and a partition number.
 * @param instr
 * @param delims
 * @param lastpos
 * @return @p
 * @note this function allocates memory that needs to be freed by caller
 **/
char *mr_strtok(char *instr, const char *delims, int *lastpos)
{

	char *token = NULL;
	char *strptr = NULL;
	size_t pos1 = 0;
	size_t pos2 = 0;

	if (strlen(instr) <= *lastpos) {
		*lastpos = 0;
		return token;
	}

	strptr = instr + *lastpos;
	pos2 = strspn(strptr, delims);
	strptr += pos2;
	pos1 = strcspn(strptr, delims);
	token = (char *)mr_malloc(sizeof(*token) * (pos1 + 1));
	strncpy(token, strptr, pos1);
	token[pos1] = '\0';
	*lastpos = *lastpos + pos1 + pos2 + 1;

	return token;
}


/**
 * Returns the string fed to it 'inptr' with all characters to escape given
 * in 'toesc' prepended by escaping character 'escchr'.
 * (Prepare strings for use in system() or popen() with this function.)
 * @param instr
 * @param toesc
 * @param escchr
 * @note this function allocates memory that needs to be freed by caller
 **/
char *mr_stresc(char *instr, char *toesc, const char escchr) {
	char *inptr = NULL;
	char *retstr = NULL;
	char *retptr = NULL;
	char *escptr = NULL;
	int cnt = 0;

	inptr = instr;

	// Count how many characters need escaping.
	while (*inptr != '\0') {
		escptr = toesc;
		while (*escptr != '\0') {
			if (*inptr == *escptr) {
				// Found it, skip the rest.
				cnt++;
				inptr++;
				break;
			}
			inptr++;
			escptr++;
		}
	}
	inptr = instr;

	retstr = (char *) mr_malloc(strlen(inptr) + cnt + 1);
	retptr = retstr;

	// Prepend specified characters with escape character.
	while (*inptr != '\0') {
		escptr = toesc;
		while (*escptr != '\0') {
			if (*inptr == *escptr) {
				// Found it, skip the rest.
				*retptr = escchr;
				retptr++;
				break;
			}
			escptr++;
		}
		*retptr = *inptr;
		retptr++;
		inptr++;
	}
	*retptr = '\0';

	return retstr;
}

/* Return a string containing the date */
char *mr_date(void) {
	
	time_t tcurr;

	tcurr = time(NULL);
	return(ctime(&tcurr));
}


/**
 * Remove all characters whose ASCII value is less than or equal to 32
 * (spaces and control characters) from both sides of @p in_out.
 * @param in_out The string to strip spaces/control characters from (modified).
 */
void mr_strip_spaces(char *in_out) {
	int i = 0;
	int j = 0;
	size_t length;

	if (in_out == NULL) {
		return;
	}
	length = strlen(in_out);

	/* Skip initial spaces and special chars */
	for (i = 0; in_out[i] <= ' ' && i < (int)length ; i++);
	/* Shift the string to the begining if needed */
	if (i != 0) {
		for (j = 0; i < (int)length ; i++, j++) {
			in_out[j] = in_out[i];
		}
		/* Erase the end of the string if needed */
		j++;
		in_out[j] = '\0';
	}

	/* Skip final spaces and special chars */
	for (i = (int)strlen(in_out) - 1; i >= 0  && in_out[i] <= ' '; i--);

	/* The string now ends after that char */
	i++;
	in_out[i] = '\0';
}
