/*---------------------------------------------------*
 | File: token.c - String parsing routines for sort. |
 | v1.00 MLO 911230 - see the comments in sort.c     |
 *---------------------------------------------------*/

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "mlo.h"
#include "sort.h"

void GetTokBlk(
  char *string,     /* String to be parsed */
  int i,            /* Field number (1, 2, ... ) */
  char *token       /* Output */
){

/*------------------------------------------------------------------*
 | This procedure splits the given string in fields separated from  |
 | one or more whitespaces, and returns in "token" the "i"-th field |
 | or an empty string if less than "i" fields are present.          |
 |                                                                  |
 | N.B.: NO CHECKS ARE DONE. Please be sure that "i" is positive    |
 | and that "token" is large enough before calling GetTokBlk().     |
 *------------------------------------------------------------------*/

/**
 | First: skip leading whitespaces (or until the end of the string).
**/

  while (*string && isspace(*string)) string++;

/**
 | Second: skip i-1 fields and their trailing whitespaces,
 | or until the end of the string.
**/

  while (--i) {
    while (*string && !isspace(*string)) string++;
    while (*string &&  isspace(*string)) string++;
  }

/**
 | Third: copy this field to the output, until the next whitespace
 | or the end of the string; terminate the output string and return.
**/

  while (*string && !isspace(*string)) *token++ = *string++;
  *token = '\0';
}

void GetTokDel(
  char *string,     /* String to be parsed */
  char *delim,      /* Delimiters between fields */
  int i,            /* Field number (1, 2, ...) */
  char *token       /* Output */
){

/*---------------------------------------------------------------*
 | This procedure examines a character string, to be splitted    |
 | in fields separated with characters from a given set of       |
 | delimiters; then returns in "token" the "i"-th field, without |
 | leading and trailing whitespaces (but including whitespaces   |
 | bounded by other characters); or an empty string if the field |
 | contains only whitespaces, or if less than "i" fields are     |
 | found.                                                        |
 |                                                               |
 | N.B.: NO CHECKS ARE DONE. Please be sure that "i" is positive |
 | and that "token" is large enough before calling GetTokDel().  |
 *---------------------------------------------------------------*/

  char *pc = token;     /* Pointer to the end of the returned string */

/**
 | First: skip characters until i-1 delimiters are found, or
 | until the end of the string. "string" points to the first
 | character in the needed field, or to the terminating '\0'.
**/

  while (--i) while (*string && !strchr(delim, *string++)) ;

/**
 | Second: skip leading whitespaces.
**/

  while (*string && isspace(*string)) string++;

/**
 | Third: copy all to "token", until the end of the string or
 | the next delimiter. Take care to have a pointer to the last
 | non-whitespace character in output (plus one).
**/

  while (*string && !strchr(delim, *string)) {
    *token = *string++;
    if (!isspace(*token++)) pc = token;
  }

/**
 | Fourth: terminate the output string, and return.
**/

  *pc = '\0';
}
