/*
 * $Id$
 *
 * Copyright © 2003 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Keith Packard not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Keith Packard makes no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

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

static void *
New (int size);

static void *
Reallocate (void *p, int size);

static void
Dispose (void *p);

typedef enum { False, True } Bool;

typedef struct {
    char    *buf;
    int	    size;
    int	    len;
} String;

static String *
StringNew (void);

static void
StringAdd (String *s, char c);

static void
StringAddString (String *s, char *buf);

static String *
StringMake (char *buf);

static void
StringDel (String *s);

static void
StringPut (FILE *f, String *s);

static void
StringDispose (String *s);

typedef struct {
    String  *tag;
    String  *text;
} Replace;

static Replace *
ReplaceNew (void);

static void
ReplaceDispose (Replace *r);

static void
Bail (const char *format, const char *arg);

static Replace *
ReplaceRead (FILE *f);

typedef struct _replaceList {
    struct _replaceList	*next;
    Replace		*r;
} ReplaceList;

static ReplaceList *
ReplaceListNew (Replace *r, ReplaceList *next);

static void
ReplaceListDispose (ReplaceList *l);

typedef struct {
    ReplaceList	*head;
} ReplaceSet;

static ReplaceSet *
ReplaceSetNew (void);

static void
ReplaceSetDispose (ReplaceSet *s);

static void
ReplaceSetAdd (ReplaceSet *s, Replace *r);

static Replace *
ReplaceSetFind (ReplaceSet *s, char *tag);

static ReplaceSet *
ReplaceSetRead (FILE *f);

typedef struct _skipStack {
    struct _skipStack	*prev;
    int			skipping;
} SkipStack;

static SkipStack *
SkipStackPush (SkipStack *prev, int skipping);

static SkipStack *
SkipStackPop (SkipStack *prev);

typedef struct _loopStack {
    struct _loopStack	*prev;
    String		*tag;
    String		*extra;
    long		pos;
} LoopStack;

static LoopStack *
LoopStackPush (LoopStack *prev, FILE *f, char *tag);

static LoopStack *
LoopStackLoop (ReplaceSet *rs, LoopStack *ls, FILE *f);

static void
LineSkip (FILE *f);

static void
DoReplace (FILE *f, ReplaceSet *s);

#define STRING_INIT 128

static void *
New (int size)
{
    void    *m = malloc (size);
    if (!m)
	abort ();
    return m;
}

static void *
Reallocate (void *p, int size)
{
    void    *r = realloc (p, size);

    if (!r)
	abort ();
    return r;
}

static void
Dispose (void *p)
{
    free (p);
}

static String *
StringNew (void)
{
    String  *s;

    s = New (sizeof (String));
    s->buf = New (STRING_INIT);
    s->size = STRING_INIT - 1;
    s->buf[0] = '\0';
    s->len = 0;
    return s;
}

static void
StringAdd (String *s, char c)
{
    if (s->len == s->size)
	s->buf = Reallocate (s->buf, (s->size *= 2) + 1);
    s->buf[s->len++] = c;
    s->buf[s->len] = '\0';
}

static void
StringAddString (String *s, char *buf)
{
    while (*buf)
	StringAdd (s, *buf++);
}

static String *
StringMake (char *buf)
{
    String  *s = StringNew ();
    StringAddString (s, buf);
    return s;
}

static void
StringDel (String *s)
{
    if (s->len)
	s->buf[--s->len] = '\0';
}

static void
StringPut (FILE *f, String *s)
{
    char    *b = s->buf;

    while (*b)
	putc (*b++, f);
}

#define StringLast(s)	((s)->len ? (s)->buf[(s)->len - 1] : '\0')

static void
StringDispose (String *s)
{
    Dispose (s->buf);
    Dispose (s);
}

static Replace *
ReplaceNew (void)
{
    Replace *r = New (sizeof (Replace));
    r->tag = StringNew ();
    r->text = StringNew ();
    return r;
}

static void
ReplaceDispose (Replace *r)
{
    StringDispose (r->tag);
    StringDispose (r->text);
    Dispose (r);
}

static void
Bail (const char *format, const char *arg)
{
    fprintf (stderr, "fatal: ");
    fprintf (stderr, format, arg);
    fprintf (stderr, "\n");
    exit (1);
}

static Replace *
ReplaceRead (FILE *f)
{
    int	    c;
    Replace *r;

    while ((c = getc (f)) != '@')
    {
	if (c == EOF)
	    return 0;
    }
    r = ReplaceNew();
    while ((c = getc (f)) != '@')
    {
	if (c == EOF)
	{
	    ReplaceDispose (r);
	    return 0;
	}
	if (isspace (c))
	    Bail ("invalid character after tag %s", r->tag->buf);
	StringAdd (r->tag, c);
    }
    if (r->tag->buf[0] == '\0')
    {
	ReplaceDispose (r);
	return 0;
    }
    while (isspace ((c = getc (f))))
	;
    ungetc (c, f);
    while ((c = getc (f)) != '@' && c != EOF)
	StringAdd (r->text, c);
    if (c == '@')
	ungetc (c, f);
    while (isspace (StringLast (r->text)))
	StringDel (r->text);
    return r;
}

static ReplaceList *
ReplaceListNew (Replace *r, ReplaceList *next)
{
    ReplaceList	*l = New (sizeof (ReplaceList));
    l->r = r;
    l->next = next;
    return l;
}

static void
ReplaceListDispose (ReplaceList *l)
{
    if (l)
    {
	ReplaceListDispose (l->next);
	ReplaceDispose (l->r);
	Dispose (l);
    }
}

static ReplaceSet *
ReplaceSetNew (void)
{
    ReplaceSet	*s = New (sizeof (ReplaceSet));
    s->head = 0;
    return s;
}

static void
ReplaceSetDispose (ReplaceSet *s)
{
    ReplaceListDispose (s->head);
    Dispose (s);
}

static void
ReplaceSetAdd (ReplaceSet *s, Replace *r)
{
    s->head = ReplaceListNew (r, s->head);
}

static Replace *
ReplaceSetFind (ReplaceSet *s, char *tag)
{
    ReplaceList	*l;

    for (l = s->head; l; l = l->next)
	if (!strcmp (tag, l->r->tag->buf))
	    return l->r;
    return 0;
}

static ReplaceSet *
ReplaceSetRead (FILE *f)
{
    ReplaceSet	*s = ReplaceSetNew ();
    Replace	*r;

    while ((r = ReplaceRead (f)))
    {
	while (ReplaceSetFind (s, r->tag->buf))
	    StringAdd (r->tag, '+');
	ReplaceSetAdd (s, r);
    }
    if (!s->head)
    {
	ReplaceSetDispose (s);
	s = 0;
    }
    return s;
}

static SkipStack *
SkipStackPush (SkipStack *prev, int skipping)
{
    SkipStack	*ss = New (sizeof (SkipStack));
    ss->prev = prev;
    ss->skipping = skipping;
    return ss;
}

static SkipStack *
SkipStackPop (SkipStack *prev)
{
    SkipStack	*ss = prev->prev;
    Dispose (prev);
    return ss;
}

static LoopStack *
LoopStackPush (LoopStack *prev, FILE *f, char *tag)
{
    LoopStack	*ls = New (sizeof (LoopStack));
    ls->prev = prev;
    ls->tag = StringMake (tag);
    ls->extra = StringNew ();
    ls->pos = ftell (f);
    return ls;
}

static LoopStack *
LoopStackLoop (ReplaceSet *rs, LoopStack *ls, FILE *f)
{
    String	*s = StringMake (ls->tag->buf);
    LoopStack	*ret = ls;
    Bool	loop;

    StringAdd (ls->extra, '+');
    StringAddString (s, ls->extra->buf);
    loop = ReplaceSetFind (rs, s->buf) != 0;
    StringDispose (s);
    if (loop)
	fseek (f, ls->pos, SEEK_SET);
    else
    {
	ret = ls->prev;
	StringDispose (ls->tag);
	StringDispose (ls->extra);
	Dispose (ls);
    }
    return ret;
}

static void
LineSkip (FILE *f)
{
    int	c;

    while ((c = getc (f)) == '\n')
	;
    ungetc (c, f);
}

static void
DoReplace (FILE *f, ReplaceSet *s)
{
    int		c;
    String	*tag;
    Replace	*r;
    SkipStack	*ss = 0;
    LoopStack	*ls = 0;
    int		skipping = 0;

    while ((c = getc (f)) != EOF)
    {
	if (c == '@')
	{
	    tag = StringNew ();
	    while ((c = getc (f)) != '@')
	    {
		if (c == EOF)
		    abort ();
		StringAdd (tag, c);
	    }
	    if (ls)
		StringAddString (tag, ls->extra->buf);
	    switch (tag->buf[0]) {
	    case '?':
		ss = SkipStackPush (ss, skipping);
		if (!ReplaceSetFind (s, tag->buf + 1))
		    skipping++;
		LineSkip (f);
		break;
	    case ':':
		if (!ss)
		    abort ();
		if (ss->skipping == skipping)
		    ++skipping;
		else
		    --skipping;
		LineSkip (f);
		break;
	    case ';':
		skipping = ss->skipping;
		ss = SkipStackPop (ss);
		LineSkip (f);
		break;
	    case '{':
		ls = LoopStackPush (ls, f, tag->buf + 1);
		LineSkip (f);
		break;
	    case '}':
		ls = LoopStackLoop (s, ls, f);
		LineSkip (f);
		break;
	    default:
		r = ReplaceSetFind (s, tag->buf);
		if (r && !skipping)
		    StringPut (stdout, r->text);
		break;
	    }
	    StringDispose (tag);
	}
	else if (!skipping)
	    putchar (c);
    }
}

int
main (int argc, char **argv)
{
    FILE	*f;
    ReplaceSet	*s;

    if (!argv[1])
	Bail ("usage: %s <template.sgml>", argv[0]);
    f = fopen (argv[1], "r");
    if (!f)
    {
	Bail ("can't open file %s", argv[1]);
	exit (1);
    }
    while ((s = ReplaceSetRead (stdin)))
    {
	DoReplace (f, s);
	ReplaceSetDispose (s);
	rewind (f);
    }
    if (ferror (stdout))
	Bail ("%s", "error writing output");
    exit (0);
}
