Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

[C] explode()

Name: Anonymous 2015-07-29 1:02

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

struct v {
void *p;
size_t n;
};

struct v **explode(const void *p, const void *q, size_t pn, size_t qn, size_t size);
void *memmem(const void *p, const void *q, size_t pn, size_t qn, size_t size);
void *memdup(const void *p, size_t n);

int main(void) {
struct v **p = explode("a b", " ", 3, 1, 1);
struct v **q = p;
if(p == NULL) {
perror(NULL);
return EXIT_FAILURE;
}
while(*p) {
fwrite((*p)->p, 1, (*p)->n, stdout);
putchar(' ');
p++;
}
putchar('\n');
p = q;
while(*p != NULL) {
free((*p)->p);
free(*p++);
}
free(q);
return 0;
}

struct v **explode(const void *p, const void *q, size_t pn, size_t qn, size_t size) {
void *tmp;
struct v **rv = NULL;
size_t i;
ptrdiff_t j;
pn *= size;
qn *= size;
for(i = 0;; i++) {
while(pn >= qn && memcmp(p, q, qn) == 0) {
p = (char *)p + qn;
pn -= qn;
}
if((tmp = realloc(rv, (i + 1) * sizeof *rv)) == NULL) {
while(i--) {
free(rv[i]->p);
free(rv[i]);
}
free(rv);
return NULL;
}
rv = tmp;
rv[i] = NULL;
if(pn == 0) break;
if((rv[i] = malloc(sizeof **rv)) == NULL) {
while(i--) {
free(rv[i]->p);
free(rv[i]);
}
free(rv);
return NULL;
}
if((tmp = memmem(p, q, pn, qn, size)) == NULL) {
if((rv[i]->p = memdup(p, pn)) == NULL) {
while(i--) {
free(rv[i]->p);
free(rv[i]);
}
free(rv);
return NULL;
}
rv[i]->n = pn;
break;
}
else {
j = (char *)tmp - (char *)p;
if((tmp = memdup(p, j)) == NULL) {
while(i--) {
free(rv[i]->p);
free(rv[i]);
}
free(rv);
return NULL;
}
rv[i]->p = tmp;
rv[i]->n = j;
p = (char *)p + j;
pn -= j;
}
}
if(rv[i] != NULL) {
if((tmp = realloc(rv, (i + 2) * sizeof *rv)) == NULL) {
i++;
while(i--) {
free(rv[i]->p);
free(rv[i]);
}
free(rv);
return NULL;
}
rv[i + 1] = NULL;
}
return rv;
}

void *memdup(const void *p, size_t n) {
void *rv = NULL;
if((rv = malloc(n)) != NULL) memcpy(rv, p, n);
return rv;
}

void *memmem(const void *p, const void *q, size_t pn, size_t qn, size_t size) {
for(; pn >= qn; p = (unsigned char *)p + 1, pn -= size)
if(memcmp(p, q, qn) == 0) return p;
return NULL;
}

Name: Cudder !cXCudderUE 2015-07-30 14:37

>>16
; in:
; esi = source
; edi = delim
; edx = source length
; ecx = delim length
; out:
; eax = ptr to splits, {ptr,len}, null-terminated, 0 on err
; all registers change, except esp and ebx
explode:
mov ebp, esp
jmp begin_loop
exploop:
push esi
push ecx
push edi
repnz cmpsb
pop edi
pop ecx
jz match
pop esi
inc esi
dec edx
jmp loop_cmp
match:
pop eax
sub eax, [esp]
push eax
sub edx, ecx
begin_loop:
push esi
loop_cmp:
cmp ecx, edx
jbe exploop
expdone:
push edx
push 0
sub ebp, esp
push ebp
shr ebp, 2
call malloc
test eax, eax
pop ecx
jz malerr
mov ecx, ebp ; not needed if malloc does not modify arg
retloop:
pop [eax+ecx*4-4]
loop retloop
malerr:
ret


One pass through p, and one "reallocation" (try doing that in C!)

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List