/*
 * dump.c - Jspell's dump mode
 *
 * Copyright 1992, 1993, Geoff Kuenning, Granada Hills, CA
 * All rights reserved.
 *
 * Copyright 1994 by Ulisses Pinto & Jose' Joa~o Almeida, Universidade do Minho
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All modifications to the source code must be clearly marked as
 *    such.  Binary redistributions based on modified source code
 *    must be clearly marked as modified versions in the documentation
 *    and/or other materials provided with the distribution.
 * 4. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgment:
 *      This product includes software developed by Geoff Kuenning and
 *      other unpaid contributors.
 * 5. The name of Geoff Kuenning may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * $Log$
 * Revision 1.3  2006/05/18 14:44:56  ambs
 * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARGH@!
 *
 * Revision 1.2  2001/06/12 07:58:05  albie
 * - changed from mktemp to mkstemp
 * - removed aclocal file
 * - added a config.h.in file to make the config.h file being generated by
 *   autoconf
 * - removed all lint stuff
 * - corrected perl makefile
 *
 * Revision 1.1.1.1  2001/03/05 08:54:31  jj
 *
 *
 * Analizador ortografico jspell
 *
 * Revision 1.00  1994/07/09
 */

#include "jsconfig.h"
#include "jspell.h"
#include "proto.h"

void               dumpmode(void);
static void        tbldump(struct flagent * flagp, int numflags);
static void        entdump(struct flagent * flagp);
static void        setdump(char * setp, int mask);
static void        subsetdump(char * setp, int mask, int dumpval);

void dumpmode()
{
   if (hashheader.flagmarker == '\\'
       ||  hashheader.flagmarker == '#'
       ||  hashheader.flagmarker == '>'
       ||  hashheader.flagmarker == ':'
       ||  hashheader.flagmarker == '-'
       ||  hashheader.flagmarker == ','
       ||  hashheader.flagmarker == '[') /* ] */
      printf("flagmarker \\%c\n", hashheader.flagmarker);
   else if (hashheader.flagmarker < ' '  ||  hashheader.flagmarker >= 0177)
      printf("flagmarker \\%3.3o\n",
             (unsigned int) hashheader.flagmarker & 0xFF);
   else
      printf("flagmarker %c\n", hashheader.flagmarker);
   if (numpflags) {
      printf("prefixes\n");
      tbldump(pflaglist, numpflags);
   }
   if (numsflags) {
      printf("suffixes\n");
      tbldump(sflaglist, numsflags);
   }
}

/*---------------------------------------------------------------------------*/

static void tbldump(flagp, numflags)   /* Dump a flag table */
register struct flagent *flagp;        /* First flag entry to dump */
register int             numflags;     /* Number of flags to dump */
{
   while (--numflags >= 0)
      entdump(flagp++);
}

/*---------------------------------------------------------------------------*/

static void entdump(flagp)             /* Dump one flag entry */
register struct flagent *flagp;        /* Flag entry to dump */
{
   register int cond;                 /* Condition number */

   printf("  flag %s%c: ",
          (flagp->flagflags & FF_CROSSPRODUCT) ? "*" : " ",
          BITTOCHAR (flagp->flagbit));
   for (cond = 0;  cond < flagp->numconds;  cond++) {
      setdump(flagp->conds, 1 << cond);
      if (cond < flagp->numconds - 1)
         putc(' ', stdout);
   }
   if (cond == 0)                        /* No conditions at all? */
      putc('.', stdout);
   printf("\t> ");
   putc('\t', stdout);
   if (flagp->stripl)
      printf("-%s,", ichartosstr(flagp->strip, 1));
   printf("%s", flagp->affl ? ichartosstr(flagp->affix, 1) : "-");
   if (flagp->jclass)
      printf("\t; %s\n", ichartosstr(flagp->jclass, 1));
}

/*---------------------------------------------------------------------------*/

static void setdump(setp, mask)   /* Dump a set specification */
register char *setp;       /* Set to be dumped */
register int   mask;       /* Mask for bit to be dumped */
{
   register int cnum;      /* Next character's number */
   register int firstnz;   /* Number of first NZ character */
   register int numnz;     /* Number of NZ characters */

   firstnz = numnz = 0;
   for (cnum = SET_SIZE;  --cnum >= 0;  ) {
      if (setp[cnum] & mask) {
         numnz++;
         firstnz = cnum;
      }
   }
   if (numnz == 1)
      putc(firstnz, stdout);
   else if (numnz == SET_SIZE)
           putc('.', stdout);
   else if (numnz > SET_SIZE / 2) {
           printf("[^");
           subsetdump(setp, mask, 0);
           putc(']', stdout);
   }
   else {
       putc('[', stdout);
       subsetdump(setp, mask, mask);
       putc(']', stdout);
   }
}

/*---------------------------------------------------------------------------*/

static void subsetdump (setp, mask, dumpval) /* Dump part of a set spec */
register char *setp;        /* Set to be dumped */
register int   mask;        /* Mask for bit to be dumped */
register int   dumpval;     /* Value to be printed */
{
   register int cnum;        /* Next character's number */
   register int rangestart;  /* Value starting a range */

   for (cnum = 0;  cnum < SET_SIZE;  setp++, cnum++) {
      if (((*setp ^ dumpval) & mask) == 0) {
         for (rangestart = cnum;  cnum < SET_SIZE;  setp++, cnum++) {
            if ((*setp ^ dumpval) & mask)
               break;
         }
         if (cnum == rangestart + 1)
            putc(rangestart, stdout);
         else if (cnum <= rangestart + 3) {
               while (rangestart < cnum) {
                  putc(rangestart, stdout);
                  rangestart++;
               }
         }
         else
            printf("%c-%c", rangestart, cnum - 1);
      }
   }
}
