/*-
 * Copyright (c)1997-2005 by Hartmut Brandt
 * 	All rights reserved.
 *
 * Author: Harti Brandt <harti@freebsd.org>
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $Begemot: libbegemot/getfields.c,v 1.5 2005/06/01 07:50:45 brandt_h Exp $
 */
# include <stdio.h>
# include <stdlib.h>
# include "begemot.h"

unsigned long delim[8] = { 0x00000201, 0x00000001 };

# define DELIM(C) (delim[(unsigned char)(C) >> 5] & (1UL << ((C) & 0x1f)))
# define SETDL(C) (delim[(unsigned char)(C) >> 5] |= (1UL << ((C) & 0x1f)))

int
getfields(char *str, char **fields, int nfields)
{
	char **fp = fields;

	while(nfields-- > 0) {
		*fp++ = str;
		while(!DELIM(*str))
			str++;
		if(nfields == 0 || *str == '\0')
			break;
		*str++ = '\0';
	}
	if(nfields > 0)
		*fp = NULL;

	return fp - fields;
}

int
getmfields(char *str, char **fields, int nfields)
{
	char **fp = fields;

	while(nfields > 0) {
		while(*str != '\0' && DELIM(*str))
			str++;
		if(*str == '\0')
			break;
		*fp++ = str;
		if(--nfields == 0)
			break;
		while(!DELIM(*str))
			str++;
		if(*str == '\0')
			break;
		*str++ = '\0';
	}

	if(nfields > 0)
		*fp = NULL;

	return fp - fields;
}

char *
setfields(char *str)
{
	static char odelim[256];
	char *p;
	int i;

	p = odelim;
	for(i = 1; i < 256; i++)
		if(DELIM(i))
			*p++ = i;
	*p = '\0';

	for(i = 0; i < 8; i++)
		delim[i] = 0;
	while(*str) {
		SETDL(*str);
		str++;
	}
	SETDL(0);

	return odelim;
}

# ifdef TEST


int
main(int argc, char *argv[])
{
	char *str, *p;
	int i, n;
	char *fields[6];

	p = setfields(" \t");
	p = cstrd(p, strlen(p));
	free(p);
	for(i = 0; i < 8; i++)
		printf("%08lx%c", delim[i], (i==7)?'\n':' ');

	while((str = readline(stdin)) != NULL) {
		str[strlen(str)-1] = '\0';
		if(str[0] == '!') {
			p = setfields(str+1);
			p = cstrd(p, strlen(p));
			printf("old: %s\n", p);
			free(p);
			for(i = 0; i < 8; i++)
				printf("%08lx%c", delim[i], (i==7)?'\n':' ');
		} else {
# ifdef TESTM
			n = getmfields(str, fields, 6);
# else
			n = getfields(str, fields, 6);
# endif
			printf("n = %d\n", n);
			for(i = 0; i < n; i++)
				printf("%d: '%s'\n", i, fields[i]);
			if(n < 6 && fields[n] == NULL)
				printf("%d: NULL\n", n);
		}
		free(str);
	}

	return 0;
}

# endif


syntax highlighted by Code2HTML, v. 0.9.1