commit d96884ab2efe1565a4492ec95d4c8d6bb810ed2a
parent 9638d22a9a85472930449602bcb6447313623b3c
Author: zerous Naveen Narayanan <zerous@nocebo.space>
Date: Sat, 9 Mar 2019 21:01:58 +0100
Fix bug - next ptr not set properly after realloc
Diffstat:
M | sw.c | | | 130 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
1 file changed, 79 insertions(+), 51 deletions(-)
diff --git a/sw.c b/sw.c
@@ -1,57 +1,55 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
-/* shuffle newline terminated strings */
+/* shuffle newline/whitespace terminated words */
void shuffle(char *, int);
+int mstrlen(char *);
+char *mstrcpy(char *, char *);
int
-main(int argc, char **argv)
+main(void)
{
- char c, *s, *n, *t;
+ int c;
+ char *beg, *next, *s;
int nword;
- size_t gf;
+ size_t siz;
- (void) argc;
- (void) argv;
-
- gf = 512;
- s = n = NULL;
+ siz = 512;
+ beg = next = NULL;
nword = 0;
for (;(c = getc(stdin)) != EOF;)
{
- if (n == NULL || n >= (s + (gf - 512))) /* first time */
+ if (next == NULL || (next - beg) >= (siz - 512)) /* first time */
{
- t = realloc(s, gf);
- if (t != NULL) {
- s = t;
- n = t;
- *n++ = c;
- gf += 512;
+ if ((s = realloc(beg, siz)) != NULL ) {
+ next = s + (next - beg);
+ beg = s;
+ *next++ = c;
+ siz += 512;
} else {
printf("err: realloc\n");
return 1;
}
}
else if (c == '\n' || c == ' ') {
- *n++ = '\0';
+ *next++ = '\0';
nword++;
}
else {
- *n++ = c;
+ *next++ = c;
}
}
- /* shuffle(s, nword); */
+ shuffle(s, nword);
- for (char *t = s; t < n;) {
+ for (char *t = beg; t < next;) {
printf("%s\n", t);
- t += strlen(t) + 1;
+ t += mstrlen(t) + 1;
}
- free(s);
+ free(beg);
return 0;
}
@@ -59,49 +57,79 @@ main(int argc, char **argv)
void
shuffle(char *s, int nword)
{
- char w[128];
+ char buf1[128], buf2[128];
+ int k, q, l;
+ char *str1, *str2;
- for (int i = 0; i < nword ; i++)
+ for (int i = 0; i < nword && nword > 1; i++)
{
- int k, q, l, r;
- char *m, *n;
-
-
+ /* get two rand word indexes */
q = rand()%(nword - 1);
- l = rand()% (nword - 1);
- k = 0;
+ l = rand()%(nword - 1);
+ k = 0;
+
for (char *t = s; k < nword; k++) {
if (k == l)
- m = t;
+ str1 = t;
else if (k == q)
- n = t;
- r = strlen(t);
- t += r + 1;
+ str2 = t;
+ t += mstrlen(t) + 1;
}
- assert(strlen(m) < 128);
- assert(strlen(n) < 128);
+ if (mstrlen(str1) > 128 || mstrlen(str2) > 128) {
+ printf("word too long\n");
+ return;
+ }
- if (strlen(m) == strlen(n)) {
- strcpy(w, m);
- strcpy(m, n);
- strcpy(n, w);
+ if (mstrlen(str1) == mstrlen(str2)) {
+ mstrcpy(buf1, str1);
+ mstrcpy(str1, str2);
+ mstrcpy(str2, buf1);
}
else {
- strcpy(w, m);
- int t = strlen(m) - strlen(n);
- if (m > n) {
- memmove((n + strlen(n) + 1 + t), (n + strlen(m) + 1),
- m - (n + strlen(n) + 1));
+ mstrcpy(buf1, str1);
+ mstrcpy(buf2, str2);
+ int t = mstrlen(str1) - mstrlen(str2);
+ if (str1 > str2) {
+ memmove((str2 + mstrlen(str2) + 1 + t), /* move words between the words being swapped */
+ (str2 + mstrlen(str2) + 1),
+ str1 - (str2 + mstrlen(str2) + 1));
+ mstrcpy(str2, buf1);
+ mstrcpy(str1 + t, buf2);
}
- else if (m < n) {
- memmove((m + strlen(m) + 1 - t), (m + strlen(m) + 1),
- n - (m + strlen(m) + 1));
+ else if (str1 < str2) {
+ memmove((str1 + mstrlen(str1) + 1 - t), /* move words between the words being swapped */
+ (str1 + mstrlen(str1) + 1),
+ str2 - (str1 + mstrlen(str1) + 1));
+ mstrcpy(str1, buf2);
+ mstrcpy(str2 - t, buf1);
}
- strcpy(m, n);
- strcpy(n, w);
}
}
}
+
+char *
+mstrcpy(char *a, char *b)
+{
+ int i;
+ for (i = 0; b[i] != '\0'; i++)
+ {
+ a[i] = b[i];
+ }
+ a[i] = '\0';
+
+ return a;
+}
+
+int
+mstrlen(char *a)
+{
+ int i;
+
+ for (i = 0; a[i] != '\0'; i++)
+ ;
+
+ return i;
+}