[ create a new paste ] login | about

Link: http://codepad.org/PtTXrlLj    [ raw code | output | fork ]

C, pasted on Nov 11:
#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 */


Output:
1
2
usage: /t -r/f.
 option -r:reverse, -f:forward


Create a new paste based on this one


Comments: