Skip to content

Instantly share code, notes, and snippets.

@bogen
Last active August 29, 2015 14:04
Show Gist options
  • Save bogen/4e9a8294a923f9f2b4b0 to your computer and use it in GitHub Desktop.
Save bogen/4e9a8294a923f9f2b4b0 to your computer and use it in GitHub Desktop.
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void nimecho (int n, ...) {
typedef char* cptr;
va_list ap;
int i;
int len = 0;
char *dst0;
char *dst;
va_start (ap, n);
for (i = 0; i < n; i++) {
va_arg (ap, cptr); // discard
len += va_arg (ap, int);
}
va_end (ap);
len += 1;
dst = dst0 = (char*) alloca (len);
va_start (ap, n);
for (i = 0; i < n; i++) {
char *src = va_arg (ap, cptr);
int slen = va_arg (ap, int);
memcpy (dst, src, slen);
dst += slen;
}
va_end (ap);
*dst = '\n';
fwrite (dst0, len, 1, stdout);
}
#define COUNT(s) s,((int)sizeof(s)-1)
void usenimecho () {
nimecho (4, COUNT("dog"), COUNT("monkey"), COUNT("bird"), COUNT("rabbits"));
}
void useprintf () {
printf ("%s%s%s%s\n", "dog", "monkey", "bird", "rabbits");
}
int main (int argc, char **argv) {
fprintf (stderr, "%d\n", argc);
if (argc < 2) return 1;
auto testnimecho = usenimecho;
switch (argv [1][0]) {
case 'p': testnimecho = useprintf; break;
case 'n': break;
case '1':
fprintf (stderr, "//useprintf\n");
useprintf ();
fprintf (stderr, "//usenimecho\n");
usenimecho ();
return 0;
case '0':
fprintf (stderr, "//printf\n");
printf ("%s\n", "foo\0cow");
fprintf (stderr, "//nimecho\n");
nimecho (1, COUNT ("foo\0cow"));
return 0;
default: return 2;
}
fprintf (stderr, "usenimecho = %p\n", usenimecho);
fprintf (stderr, "useprintf = %p\n", useprintf);
fprintf (stderr, "%c\n", argv [1][0]);
fprintf (stderr, "testnimecho = %p\n", testnimecho);
for (auto i = 0; i < 9200000; i++) {
testnimecho ();
}
return 0;
}
$ g++ -std=c++11 -Wall -Werror -o nimecho nimecho.c
$ ./nimecho 0
2
//printf
foo
//nimecho
foocow
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment