#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

#define xfree(x) free(x)
#define xmalloc malloc
#define xstrdup strdup

/* Everything but main is a tme tested function */
/* split first word off of rest and put it in first */
char *splitc(char *first, char *rest, char divider)
{
   char *p;
   p = strchr(rest, divider);
   if (p == NULL) {
      if ((first != rest) && (first != NULL))
	 first[0] = 0;
      return first;
   }
   *p = 0;
   if (first != NULL)
      strcpy(first, rest);
   if (first != rest)
      strcpy(rest, p + 1);
   return (char *) first;
}

#define  ssplit(first, rest) splitc(first, rest, ' ')

char *rmspace(char *s)
{
   register char *p;
   /* wipe end of string */
   for (p = s + strlen(s) - 1; ((isspace(*p)) && (p >= s)); p--);
   if (p != s + strlen(s) - 1)
      *(p + 1) = 0;
   for (p = s; ((isspace(*p)) && (*p)); p++);
   if (p != s)
      strcpy(s, p);
   return (char *) s;
}

/* used to queue a lot of things */
struct queue_t {
   char *item;
   struct queue_t *next;
};
typedef struct queue_t queue;

/* **** LINKED LISTS **** */

/* add something to a queue */
queue *addq(char *ss, queue * q)
{
   queue *ll, *z;
   char *s, *ptr, *p;

   s = xstrdup(ss);
   ptr = xmalloc(strlen(ss));

   do {
      p = strchr(s, ',');
      if (p != NULL) {
	 *p = 0;
	 p++;
	 strcpy(ptr, p);
      } else
	 *ptr = 0;
      rmspace(s);
      rmspace(ptr);
      ll = (queue *) xmalloc(sizeof(queue));
      ll->next = NULL;
      ll->item = (char *) xmalloc(strlen(s) + 1);
      strcpy(ll->item, s);
      if (q == NULL)
	 q = ll;
      else {
	 z = q;
	 while (z->next != NULL)
	    z = z->next;
	 z->next = ll;
      }
      *s = 0;
      strcpy(s, ptr);
   }
   while (s[0]);

   xfree(s);
   xfree(ptr);
   return q;
}

/* remove someone from a queue */
queue *delq(char *s, queue * q, int *ok)
{
   queue *ll, *list, *old;
   ll = q;
   list = q;
   old = q;
   *ok = 0;
   while (ll != NULL) {
      if (strcasecmp(ll->item, s) == 0) {
	 if (ll == list) {
	    list = (ll->next);
	    xfree(ll->item);
	    xfree(ll);
	    ll = list;
	 } else {
	    old->next = ll->next;
	    xfree(ll->item);
	    xfree(ll);
	    ll = old->next;
	 }
	 *ok = 1;
      } else {
	 old = ll;
	 ll = ll->next;
      }
   }
   return list;
}

/* clear out a list */
void clearq(queue * list)
{
   queue *ll, *q;
   ll = list;
   while (ll != NULL) {
      q = ll->next;
      xfree(ll->item);
      xfree(ll);
      ll = q;
   }
}

size_t qsize(queue * list)
{
   queue *ll;
   size_t size = 0;

   for (ll = list; ll != NULL; ll = ll->next, size++);
   return size;
}


struct queue_t *flatten_string(struct queue_t *ll, char *buf)
{
   char word[BUFSIZ];
   char tmp[BUFSIZ];
   static char *p;
   size_t i;

   if ((p = strchr(buf, '\n')) != NULL)
      *p = 0;
   if ((p = strchr(buf, '\r')) != NULL)
      *p = 0;
   for (i = 0; i < strlen(buf); i++) {
      if (isspace(buf[i]))
	 buf[i] = ' ';
      switch (buf[i]) {
	 case '\t':
	 case '*':
	 case '|':
	 case '(':
	 case ')':
	 case '=':
	 case '>':
	 case '<':
	    buf[i] = ' ';
	    break;
      }
   }
   rmspace(buf);
   if (!*buf)
      return ll;
   strcpy(word, buf);
   strcpy(buf, "");
   while (*word) {
      ssplit(tmp, word);
      rmspace(word);
      if (!*tmp) {
	 if (strchr(word, '/') != NULL) {
	    ll = addq(word, ll);
	 }
	 break;
      }
      if (strchr(tmp, '/') != NULL)
	 ll = addq(tmp, ll);
   }
   return ll;
}

struct queue_t *flatten_file(struct queue_t *ll, char *fname)
{
   char buf[BUFSIZ];
   FILE *fp;

   if ((fp = fopen(fname, "r")) == NULL)
      return ll;
   while ((fgets(buf, sizeof(buf), fp)) != NULL) {
      ll = flatten_string(ll, buf);
   }
   return ll;
}

int main()
{
   struct queue_t *deps, *dep;
   int i;
   deps = dep = NULL;

   deps = flatten_file(deps,
		       "/var/db/pkg/media-video/mplayer-1.0_pre7/DEPEND");
   for (dep = deps; dep != NULL; dep = dep->next) {
      puts(dep->item);
   }
   clearq(deps);
   return 0;
}
