aboutsummaryrefslogtreecommitdiff
path: root/src/utils.c
blob: c837eb5770ebeed4f698082c1f0b8fabfb20c3e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
 * utils.c
 *
 * Utility stuff
 *
 * (c) 2008 Thomas White <taw27@cam.ac.uk>
 *
 *  thrust3d - a silly game
 *
 */

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

#include <string.h>
#include <stdlib.h>

#include "utils.h"

void chomp(char *a) {

	unsigned int i;
	
	for ( i=0; i<strlen(a); i++ ) {
		if ( a[i] == '\n' ) {
			a[i] = '\0';
			return;
		}
	}

}

/* Return non-zero if c is in delims */
static int assplode_isdelim(const char c, const char *delims) {
	size_t i;
	for ( i=0; i<strlen(delims); i++ ) {
		if ( c == delims[i] ) return 1;
	}
	return 0;
}

static int assplode_extract(char ***pbits, int n, size_t n_captured, size_t start, const char *a) {
	char **bits = *pbits;
	bits = realloc(bits, sizeof(char *)*(n+1));
	bits[n] = malloc(n_captured+1);
	memcpy(bits[n], a+start, n_captured);
	bits[n][n_captured] = '\0';
	n++;
	*pbits = bits;
	return n;
}

/* Split the string 'a' using 'delims' as a zero-terminated list of deliminators.
 * Store each segment in bits[0...n] where n is the number of segments and is the
 *  return value.  pbits = &bits
 * Each segment needs to be freed with free() when finished with.
 * The array of bits also needs to be freed with free() when finished with, unless
 *  n=0 in which case bits==NULL
 */
int assplode(const char *a, const char *delims, char ***pbits, AssplodeFlag flags) {

	size_t i, start, n_captured;
	int n, last_was_delim;
	char **bits;
	
	n = 0;
	i = 0;
	n_captured = 0;
	start = 0;
	last_was_delim = 0;
	bits = NULL;
	while ( i < strlen(a) ) {
	
		if ( assplode_isdelim(a[i], delims) ) {
			
			if ( n_captured > 0 ) {
				/* This is a deliminator after a sequence of non-deliminator chars */
				n = assplode_extract(&bits, n, n_captured, start, a);
			}
			
			n_captured = 0;
			if ( (flags & ASSPLODE_DUPS) && last_was_delim ) {
				n = assplode_extract(&bits, n, 0, start, a);
			}
			last_was_delim = 1;
			
		} else {
			
			if ( n_captured == 0 ) {
				/* No characters currently found, so this is the start */
				start = i;
			}
			n_captured++;
			last_was_delim = 0;
			
		}
		
		i++;
	
	}
	/* Left over characters at the end? */
	if ( n_captured > 0 ) {
		n = assplode_extract(&bits, n, n_captured, start, a);
	}
	
	*pbits = bits;
	return n;

}