[ create a new paste ] login | about

Link: http://codepad.org/8QqUqc81    [ raw code | fork ]

C, pasted on May 26:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.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

#define ID_GETLINE  1001
#define ID_NODE     1002
#define ID_STR      1004
#define ID_WORDDATA 1005

#define BUFFSIZE 3 /* >= 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 {
  void *data;
  struct node *left;
  struct node *right;
};

void *push(struct node **root, void *data, int (*cmp)(void *, void *)) {
  struct node *p;
  int c;
  if (!*root) {
    p = xmalloc(sizeof(struct node), ID_NODE);
    p->data = data;
    p->left = p->right = NULL;
    *root = p;
    return data;
  } 
  if ((c = (*cmp)(data, (*root)->data)) != 0) {
    if (c < 0) {
      return push(&((*root)->left), data, cmp);
    } else if (c > 0) {
      return push(&((*root)->right), data, cmp);
    }
  }
  return (*root)->data;
}

void *pop(struct node **root) {
  struct node *p;
  void *data;
  if (*root == NULL) {
    return NULL;
  }
  if ((*root)->left) {
    data = pop(&((*root)->left));
    return data;
  }
  assert((*root)->left == NULL);
  p = *root;
  data = p->data;
  *root = p->right;
  xfree(p, ID_NODE);
  return data;
}

struct worddata {
  char *word;
  int n;
};

int isDelimiter(char c) {
  return iscntrl(0xff & c) || isdigit(0xff & c) || (isprint(0xff & c) && !isalpha(0xff & c));
}

int cmp(struct worddata *s, struct worddata *t) {
  return strcmp(s->word, t->word);
}

void wdregister(char *p, struct node **root) {
  char *word;
  struct worddata *wd, *already;
  word = xmalloc(strlen(p) + 1, ID_STR);
  if (!word) {
    fprintf(stderr, "cannot allocate enough memory, aborted.\n");
    exit(-1);
  }
  strcpy(word, p);
  wd = xmalloc(sizeof(struct worddata), ID_WORDDATA);
  if (!wd) {
    fprintf(stderr, "cannot allocate enough memory, aborted.\n");
    exit(-1);
  }
  wd->word = word;
  wd->n = 1;
  if ((already = push(root, wd, (int (*)(void *, void *))cmp)) != wd) {
    xfree(wd->word, ID_STR);
    xfree(wd, ID_WORDDATA);
    already->n++;
  }
}

void analyze_line(char *line, struct node **root) {
  char *p, *q;
  for (p = line; *p;) {
    for (;isDelimiter(*p) && *p; p++)
      ;
    if (!*p)
      break;
    for (q = p; !isDelimiter(*q) && *q; q++)
      ;
    if (*q) {
      *q = '\0';
      wdregister(p, root);
      p = q + 1;
    } else {
      wdregister(p, root);
      break;
    }
  }
}

int main() {
  struct node *root;
  struct worddata *p;
  char *line;
  root = NULL;
  while ((line = mygetline(stdin)) != NULL) {
    analyze_line(line, &root);
    xfree(line, ID_GETLINE);
  }
  while ((p = pop(&root)) != NULL) {
    printf("%s: %d\n", p->word, p->n);
    xfree(p->word, ID_STR);
    xfree(p, ID_WORDDATA);
  }
  xmallocdump();
  return 0;
}
/* end */


Output:
No errors or program output.


Create a new paste based on this one


Comments: