#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
/* #define DEBUG */
#if defined(DEBUG)
#include "xmalloc.h"
#else
#define xmalloc(x, y) malloc(x)
#define xfree(x, y) free(x)
#define xrealloc(x, y, z) realloc(x, y)
#define xmallocdump()
#endif
/* for xmalloc.c */
#define ID_GETLINE 1004
#define ID_NODE 1005
#define BUFFSIZE 1024 /* >= 2 */
char *mygetline(FILE *fp) {
static char inbuff[BUFFSIZE];
char *outbuff_malloc, *tmpbuff;
char *p, *r;
int fEOL;
if ((outbuff_malloc = xmalloc(1, ID_GETLINE)) == NULL) {
return NULL;
}
*outbuff_malloc = '\0';
fEOL = 0;
do {
r = fgets(inbuff, BUFFSIZE, fp);
if (r == NULL)
break;
for (p = inbuff; *p != '\0'; p++)
;
if (*(p - 1) == '\n')
fEOL = 1;
if ((tmpbuff = xrealloc(outbuff_malloc, strlen(outbuff_malloc) + strlen(inbuff) + 1, ID_GETLINE)) == NULL) {
xfree(outbuff_malloc, ID_GETLINE);
return NULL;
}
strcat(tmpbuff, inbuff);
outbuff_malloc = tmpbuff;
} while (!fEOL);
if (strlen(outbuff_malloc) > 0) {
for (p = outbuff_malloc; *p != '\0'; p++)
;
if (*(p - 1) == '\n')
*(p - 1) = '\0';
return outbuff_malloc;
}
xfree(outbuff_malloc, ID_GETLINE);
return NULL;
}
struct node {
char *data;
struct node *next;
struct node *prev;
};
void push_head(struct node **root, char *data) {
struct node *p;
if ((p = xmalloc(sizeof(struct node), ID_NODE)) != 0) {
p->data = data;
p->next = *root;
if (*root == 0) {
p->prev = p;
} else {
p->prev = (*root)->prev;
p->prev->next = p;
p->next->prev = p;
}
*root = p;
}
}
void push_tail(struct node **root, char *data) {
struct node *p;
if ((p = xmalloc(sizeof(struct node), ID_NODE)) != 0) {
p->data = data;
p->next = *root;
if (*root == 0) {
p->prev = p;
*root = p;
} else {
p->prev = (*root)->prev;
p->prev->next = p;
p->next->prev = p;
}
}
}
char *pop(struct node **root) {
char *r;
struct node *p;
if (*root == 0)
return 0;
p = *root;
r = p->data;
if (p->next == p) {
assert(p->prev == p);
*root = 0;
xfree(p, ID_NODE);
return r;
} else {
p->next->prev = p->prev;
p->prev->next = p->next;
*root = p->next;
xfree(p, ID_NODE);
return r;
}
}
int main(int argc, char *argv[]) {
char *p;
int flag_reverse;
struct node *root;
if (argc != 2) {
usage:
fprintf(stderr, "usage: %s -r/f.\n option -r:reverse, -f:forward\n", argv[0]);
exit(1);
}
if (*argv[1] == '-') {
if (*(argv[1] + 1) == 'f')
flag_reverse = 0;
else if (*(argv[1] + 1) == 'r')
flag_reverse = 1;
else
goto usage;
} else {
goto usage;
}
root = 0;
while ((p = mygetline(stdin)) != 0)
if (flag_reverse)
push_head(&root, p);
else
push_tail(&root, p);
putchar('\n');
while ((p = pop(&root)) != 0) {
printf("%s\n", p);
xfree(p, ID_GETLINE);
}
xmallocdump();
return 0;
}
/* end */