/*
 *  $Id: jishoop.c,v 1.6 2003/06/07 02:23:58 hiroo Exp $
 */

/*
 * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
 * This file is part of FreeWnn.
 * 
 * Copyright Kyoto University Research Institute for Mathematical Sciences
 *                 1987, 1988, 1989, 1990, 1991, 1992
 * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
 * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
 * Copyright FreeWnn Project 1999, 2000, 2003
 *
 * Maintainer:  FreeWnn Project   <freewnn@tomo.gr.jp>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#if defined(HAVE_CONFIG_H)
#include <config.h>
#endif

#include <stdio.h>

#if defined(HAVE_SYS_TYPES_H)
#include <sys/types.h>
#endif

#include "commonhd.h"
#include "de_header.h"
#include "jdata.h"

static void make_space ();
static int word_add1 (), word_delete1 (), word_comment_set1 ();

#ifndef min
#define min(a, b) ((a > b)? b:a)
#define max(a, b) ((a < b)? b:a)
#endif

int
word_add (envi, dic_no, yomi, kanji, hinsi, hindo, comment)
     int envi;
     int dic_no;
     w_char *yomi;
     w_char *kanji, *comment;
     int hinsi, hindo;
{
  int fid, k;
  struct JT *jtl;
  struct HJT *hjtl;
  int serial;

  if (Strlen (yomi) >= LENGTHYOMI)
    {
      wnn_errorno = WNN_YOMI_LONG;
      return (-1);
    }
  if (Strlen (kanji) + Strlen (comment) + Strlen (yomi) >= LENGTHKANJI)
    {
      wnn_errorno = WNN_KANJI_LONG;
      return (-1);
    }
  if (Strlen (yomi) == 0)
    {
      wnn_errorno = WNN_NO_YOMI;
      return (-1);
    }
  if (!dic_in_envp (dic_no, envi))
    {
      wnn_errorno = WNN_DICT_NOT_IN_ENV;
      return (-1);
    }
  if (dic_table[dic_no].rw == WNN_DIC_RDONLY)
    {
      wnn_errorno = WNN_RDONLY;
      return (-1);
    }

  jtl = (struct JT *) (files[dic_table[dic_no].body].area);

  if (jtl->syurui == WNN_STATIC_DICT)
    {
      wnn_errorno = WNN_NOT_A_UD;
      return (-1);
    }

  if (wnn_get_hinsi_name (hinsi) == NULL)
    {
      return (-1);
    }
  if (jtl->syurui == WNN_UD_DICT)
    {
      if ((serial = word_add1 (jtl, yomi, hinsi, kanji, comment)) == -1)
        return (-1);
    }
  else
    {                           /* jtl->syurui == WNN_REV_DICT || CWNN_REV_DICT */
      if ((serial = rd_word_add1 (jtl, yomi, hinsi, kanji, comment)) == -1)
        return (-1);
    }
  if (dic_table[dic_no].hindo != -1)
    {
      hjtl = (struct HJT *) (files[dic_table[dic_no].hindo].area);
      if (serial >= hjtl->maxserial)
        {
          if (serial >= hjtl->bufsize_serial)
            {
              hindo_file_realloc (hjtl);
            }
          hjtl->maxserial = jtl->maxserial;
        }
      hjtl->hindo[serial] = asshuku (hindo) | 0x80;
      hjtl->hdirty = 1;
    }
  else
    {
      jtl->hindo[serial] = asshuku (hindo) | 0x80;
      jtl->hdirty = 1;
    }
/* Since other hindo file may be used with this dictionary,
   update the size of such hindo file */
  fid = dic_table[dic_no].body;
  for (k = 0; k < MAX_DIC; k++)
    {
      if (dic_table[k].body == fid && dic_table[k].hindo != -1)
        {
          hjtl = (struct HJT *) (files[dic_table[k].hindo].area);
          if (serial >= hjtl->maxserial)
            {
              if (serial >= hjtl->bufsize_serial)
                {
                  hindo_file_realloc (hjtl);
                }
              hjtl->maxserial = jtl->maxserial;
              hjtl->hindo[serial] = 0;
              hjtl->hdirty = 1;
            }
        }
    }

  jtl->dirty = 1;
  return (0);
}


int
word_comment_set (envi, dic_no, serial, comment)
     int envi;
     int dic_no;
     int serial;
     w_char *comment;
{
  w_char yomi[LENGTHYOMI];
  struct JT *jtl;

  if (!dic_in_envp (dic_no, envi))
    {
      wnn_errorno = WNN_DICT_NOT_IN_ENV;
      return (-1);
    }

  if (dic_table[dic_no].rw == WNN_DIC_RDONLY)
    {
      wnn_errorno = WNN_RDONLY;
      return (-1);
    }

  jtl = (struct JT *) (files[dic_table[dic_no].body].area);

  if (jtl->syurui == WNN_STATIC_DICT)
    {
      wnn_errorno = WNN_NOT_A_UD;
      return (-1);
    }

  if (serial >= jtl->maxserial || serial < 0)
    {
      wnn_errorno = WNN_WORD_NO_EXIST;
      return (-1);
    }
  get_yomi_from_serial (dic_no, serial, yomi);
  jtl->dirty = 1;
  return (word_comment_set1 ((struct JT *) (files[dic_table[dic_no].body].area), yomi, serial, comment));
}


int
word_delete (envi, dic_no, serial)
     int envi;
     int dic_no;
     int serial;
{
  w_char yomi[LENGTHYOMI];
  struct JT *jtl;
  struct HJT *hjtl;
  int x, fid, k;

  if (!dic_in_envp (dic_no, envi))
    {
      wnn_errorno = WNN_DICT_NOT_IN_ENV;
      return (-1);
    }

  if (dic_table[dic_no].rw == WNN_DIC_RDONLY)
    {
      wnn_errorno = WNN_RDONLY;
      return (-1);
    }

  jtl = (struct JT *) (files[dic_table[dic_no].body].area);
  if (dic_table[dic_no].hindo != -1)
    {
      hjtl = (struct HJT *) (files[dic_table[dic_no].hindo].area);
    }
  else
    hjtl = NULL;

  if (jtl->syurui == WNN_STATIC_DICT)
    {
      wnn_errorno = WNN_NOT_A_UD;
      return (-1);
    }

  if ((serial >= jtl->maxserial) || (serial < 0))
    {
      wnn_errorno = WNN_WORD_NO_EXIST;
      return (-1);
    }
  if (get_yomi_from_serial (dic_no, serial, yomi) == -1)
    {
      wnn_errorno = WNN_WORD_NO_EXIST;
      return (-1);
    }
  jtl->dirty = 1;
  if (jtl->syurui == WNN_UD_DICT)
    {
      x = word_delete1 (jtl, hjtl, yomi, serial);
#if     defined(CONVERT_by_STROKE) || defined(CONVERT_with_SiSheng)
    }
  else if ((jtl->syurui & 0xff) == WNN_REV_DICT)
    {
#else
    }
  else if (jtl->syurui == WNN_REV_DICT)
    {
#endif /* CONVERT_by_STROKE || CONVERT_with_SiSheng */
      x = rd_word_delete1 (jtl, hjtl, serial);
    }
  else
    {
      wnn_errorno = WNN_NOT_A_UD;
      x = -1;
    }
  if (x == -1)
    return (-1);
/* Since other hindo file may be used with this dictionary,
   update the size of such hindo file */
  fid = dic_table[dic_no].body;
  for (k = 0; k < MAX_DIC; k++)
    {
      if (dic_table[k].body == fid && dic_table[k].hindo != -1)
        {
          hjtl = (struct HJT *) (files[dic_table[k].hindo].area);
          if (jtl->maxserial != hjtl->maxserial)
            {
              hjtl->maxserial = jtl->maxserial;
              hjtl->hdirty = 1;
            }
        }
    }
  return (0);
}


static int
word_add1 (jtl, pyomi, hinsi, kanji, comment)
     struct JT *jtl;
     int hinsi;
     w_char *kanji, *comment;
     w_char *pyomi;
{
  register struct uind1 *tary;
  register struct uind2 *hopter, *hopter1;
  register int key, key0, keye;
  register struct uind2 *hop;
  int len = Strlen (pyomi);
  int serial = jtl->maxserial;
  w_char yomi[LENGTHYOMI];

  Sreverse (yomi, pyomi);

  if ((jtl->bufsize_hontai <= jtl->maxhontai + sizeof (struct uind2) + Strlen (yomi))
      && (!ud_realloc_hontai (jtl)))
    {
      return (-1);
    }
  if ((jtl->bufsize_kanji <= jtl->maxkanji + (Strlen (kanji) + Strlen (comment) + Strlen (yomi) + 3) * sizeof (w_char) + 1)
      && (!ud_realloc_kanji (jtl)))
    {
      return (-1);
    }
  if (jtl->bufsize_serial <= jtl->maxserial + 4
     && !ud_realloc_serial (jtl))
    {
      return (-1);
    }
  if (jtl->bufsize_table <= jtl->maxtable + sizeof (struct uind1)
     && !ud_realloc_table (jtl))
    {
      return (-1);
    }

  tary = jtl->table;
  hopter = (struct uind2 *) (jtl->hontai + jtl->maxhontai);

  key = binary1 (tary, yomi, jtl->maxtable, jtl);
  if (key < 0 || Strcmpud (&tary[key], yomi, jtl))
    {                           /* No entry with same yomi */
      key += 1;
      for (key0 = key - 1; key0 >= 0; key0 = tary[key0].pter1)
        {
            hop = (struct uind2 *) (jtl->hontai + tary[key0].pter);
          if (Substrud (&tary[key0], yomi, hop->yomi[0], jtl))
            {
              break;
            }
        }
      make_space (tary, key, jtl);
      for (keye = key + 1; keye < jtl->maxtable && Substrstud (yomi, &tary[keye], jtl); keye++)
        {
          if (tary[keye].pter1 == key0)
            tary[keye].pter1 = key;
        }
      tary[key].pter1 = key0;
      tary[key].yomi2 = 0;
      tary[key].yomi1 = yomi[0] << 16;
      if (yomi[1])
        {
          tary[key].yomi1 |= yomi[1];
          if (yomi[2])
            {
              tary[key].yomi2 = yomi[2] << 16;
              if (yomi[3])
                {
                  tary[key].yomi2 |= yomi[3];
                }
            }
        }
      tary[key].pter = 0;
    }
  else
    {
      hopter1 = (struct uind2 *) (tary[key].pter + (char *) (jtl->hontai));
      while (1)
        {
          w_char kanji1[LENGTHKANJI];
          w_char comment1[LENGTHKANJI];
          if (jtl->hinsi[hopter1->serial] == hinsi)
            {
              Get_kanji (hopter1->kanjipter + jtl->kanji, yomi, Strlen (yomi), kanji1, NULL, comment);
              if (Strcmp (kanji, kanji1) == 0)
                {
                  /* Same hinsi, same kanji, same yomi */
                  if (Strcmp (comment, comment1) != 0)
                    {
                      /* set_comment */
                      hopter1->kanjipter = jtl->maxkanji;
                      kanjiadd (jtl, kanji, yomi, comment);
                    }
                  return (hopter1->serial);
                }
            }
          if (hopter1->next == 0)
            break;
               hopter1 = (struct uind2 *) (hopter1->next + (char *) (jtl->hontai));
        }
    }
  hopter->next = tary[key].pter;
  hopter->serial = jtl->maxserial++;
  jtl->gosuu++;
  hopter->kanjipter = jtl->maxkanji;
  hopter->kosuu = 1;
  hopter->yomi[0] = len;
  Strncpy (hopter->yomi + 1, yomi + 4, len - 4);
  tary[key].pter = (char *) hopter - (char *) (jtl->hontai);
  jtl->maxhontai = (char *) (AL_INT (&(hopter->yomi[0]) + 1 + max ((len - 4), 0))) - (char *) (jtl->hontai);
  jtl->hinsi[serial] = hinsi;
  jtl->hindo[serial] = 0;       /* Hindo is set later on upper module */
  kanjiadd (jtl, kanji, yomi, comment);

  return (serial);
}

void
kanjiadd (jtl, kanji, yomi, comment)
     struct JT *jtl;
     w_char *kanji, *comment, *yomi;
{
  register UCHAR *dest = jtl->kanji + jtl->maxkanji;
  long len;

#if     defined(CONVERT_by_STROKE) || defined(CONVERT_with_SiSheng)
  if ((jtl->syurui & 0xff) != WNN_REV_DICT)
    {
#else
  if (jtl->syurui != WNN_REV_DICT)
    {
#endif /* CONVERT_by_STROKE || CONVERT_with_SiSheng */
      yomi = NULL;
    }
  len = (long) kanjiaddr (dest, kanji, yomi, comment);
  jtl->maxkanji += len;
}

static void
make_space (tary, key, jtl)
     register struct JT *jtl;
     register struct uind1 *tary;
     register int key;
{
  register struct uind1 *p, *p1, *pend;
  int end = jtl->maxtable;

  pend = tary + key;
  for (p = tary + end - 1, p1 = tary + end; p >= pend; p--, p1--)
    {
      *p1 = *p;                 /* struct no dainyuu! */
      if (p1->pter1 >= key)
        p1->pter1++;
    }
  jtl->maxtable++;
}

static void
remove_space (tary, key, jtl, newkey)
     register struct JT *jtl;
     register struct uind1 *tary;
     register int key, newkey;
{
  register struct uind1 *p, *p1, *pend;
  register int end = jtl->maxtable;

  pend = tary + end;
  for (p = tary + key + 1, p1 = tary + key; p < pend; p++, p1++)
    {
      *p1 = *p;
      if (p1->pter1 > key)
        p1->pter1--;
      else if (p1->pter1 == key)
        p1->pter1 = newkey;
    }
  jtl->maxtable--;
}

int
dic_in_envp (dic_no, envi)
     int dic_no;
     int envi;
{
  register int k;

  for (k = 0; k < env[envi]->jishomax; k++)
    {
      if (env[envi]->jisho[k] == dic_no)
        {
          return (1);
        }
    }
  return (0);
}

static int
word_delete1 (jtl, hjtl, yomi, serial)
     struct JT *jtl;
     struct HJT *hjtl;
     w_char *yomi;
     int serial;
{
  int k;
  register struct uind2 *hopter;
  register struct uind2 *p;
  register struct uind1 *tary;
  register int ind1;
  int *next_pter;
  UCHAR *c;
  int tmp;

  tary = jtl->table;

  ind1 = binary (tary, yomi, jtl->maxtable, jtl);
  if (ind1 == -1)
    {
      wnn_errorno = WNN_WORD_NO_EXIST;
      return (-1);
    }

  for (next_pter = &(tary[ind1].pter), p = ((struct uind2 *) ((tary[ind1].pter) + jtl->hontai));; next_pter = &p->next, p = ((struct uind2 *) ((p->next) + jtl->hontai)))
    {

      if ((int) p->serial <= (int) serial && (int) p->serial + (int) p->kosuu > (int) serial)
        goto found_it;
      if (p->next == ENDPTR)
        break;
    }
  wnn_errorno = WNN_WORD_NO_EXIST;
  return (-1);

found_it:
  if (p->kosuu == 1)
    {
      *next_pter = p->next;
      if (tary[ind1].pter == 0)
        remove_space (tary, ind1, jtl, tary[ind1].pter1);
      if (p->serial == jtl->maxserial - 1)
        {
          jtl->maxserial--;
          if (hjtl)
            hjtl->maxserial--;
        }
      if ((int) p->kanjipter + (int) *(p->kanjipter + jtl->kanji) >= (int) jtl->maxkanji)
        {
          jtl->maxkanji = p->kanjipter;
        }
      if (jtl->maxhontai + (char *) (jtl->hontai) == (char *) (AL_INT (&(p->yomi[0]) + 1 + max (((int) p->yomi[0] - 4), 0))))
        {
          jtl->maxhontai = (char *) p - (char *) (jtl->hontai);
        }
    }
  else if (p->serial == serial)
    {
      p->kosuu -= 1;
      p->serial += 1;
      p->kanjipter += *(p->kanjipter + jtl->kanji);
    }
  else if (p->serial + p->kosuu - 1 == serial)
    {
      p->kosuu -= 1;
    }
  else
    {                           /* devide left space into 2 */

      if (jtl->bufsize_hontai <= jtl->maxhontai + sizeof (struct uind2) + Strlen (yomi))
        {
          tmp = (char *) p - (char *) jtl->hontai;
          if (ud_realloc_hontai (jtl) == 0)
            {
              return (-1);
            }
          error1 ("Realloc in Word_delete for serial %d\n", serial);
          p = (struct uind2 *) (tmp + jtl->hontai);

        }
      hopter = (struct uind2 *) (jtl->hontai + jtl->maxhontai);
      hopter->next = p->next;
      hopter->serial = serial + 1;

      for (k = 0, c = p->kanjipter + jtl->kanji; k < serial - p->serial + 1; k++)
        {
          c += *c;
        }
      hopter->kanjipter = c - jtl->kanji;

      hopter->kosuu = p->kosuu - (serial - p->serial) - 1;
      hopter->yomi[0] = p->yomi[0];
      Strncpy (hopter->yomi + 1, p->yomi + 1, max (((int) p->yomi[0] - 4), 0));
      p->next = (char *) hopter - (char *) (jtl->hontai);
      jtl->maxhontai = (char *) (AL_INT (&(hopter->yomi[0]) + 1 + max (((int) p->yomi[0] - 4), 0))) - (char *) (jtl->hontai);

      p->kosuu = serial - p->serial;
    }
  jtl->hinsi[serial] = SAKUJO_HINSI;
  jtl->gosuu--;
  return (0);
}


static int
word_comment_set1 (jtl, yomi, serial, comment)
     struct JT *jtl;
     w_char *yomi;
     int serial;
     w_char *comment;
{
  int k;
  register struct uind2 *p;
  register struct uind1 *tary;
  register int ind1;
  UCHAR *kptr;
  w_char yomi1[LENGTHYOMI], kanji[LENGTHKANJI], ocomment[LENGTHKANJI];

  tary = jtl->table;

  if (jtl->syurui == WNN_UD_DICT)
    {
      ind1 = binary (tary, yomi, jtl->maxtable, jtl);
      if (ind1 == -1)
        {
          wnn_errorno = WNN_WORD_NO_EXIST;
          return (-1);
        }

      for (p = ((struct uind2 *) ((tary[ind1].pter) + jtl->hontai));; p = ((struct uind2 *) ((p->next) + jtl->hontai)))
        {

          if ((int) p->serial <= (int) serial && (int) p->serial + (int) p->kosuu > (int) serial)
            {
              kptr = p->kanjipter + jtl->kanji;
              for (k = serial - p->serial; k > 0; k--)
                {
                  kptr += *kptr;
                }
              goto found_it;
            }
          if (p->next == ENDPTR)
            break;
        }
      wnn_errorno = WNN_WORD_NO_EXIST;
      return (-1);
    }
  else
    {
      kptr = jtl->kanji + (jtl->ri2)[serial].kanjipter;
    }
found_it:
  get_kanji_str (kptr, kanji, yomi1, ocomment);
  if (Strlen (ocomment) > Strlen (comment))
    {
      w_char *com, *kan, *yom;
      Get_kanji_str_r (kptr, &kan, &yom, &com);
      Strcpy (com, comment);
    }
  else
    {
      if (jtl->bufsize_kanji <= jtl->maxkanji + (Strlen (kanji) + Strlen (comment) + Strlen (yomi1) + 4) * 2)
        {
          if (ud_realloc_kanji (jtl) == 0)
            {
              return (-1);
            }
        }
      *(kptr + 1) = FORWARDED;
      *(w_char *) (kptr + 2) = (jtl->maxkanji + jtl->kanji - kptr) >> 16;
      *(w_char *) (kptr + 4) = (jtl->maxkanji + jtl->kanji - kptr) & 0xffff;

      kanjiadd (jtl, kanji, yomi1, comment);
#if     defined(CONVERT_by_STROKE) || defined(CONVERT_with_SiSheng)
      if ((jtl->syurui & 0xff) == WNN_REV_DICT)
        {
#else
      if (jtl->syurui == WNN_REV_DICT)
        {
#endif /* CONVERT_by_STROKE || CONVERT_with_SiSheng */
          /* We need to spend one serial_no to ensure that the entry
             before this and after this are not connected */
          if (jtl->bufsize_serial <= jtl->maxserial + 4
	     && ud_realloc_serial (jtl) == 0)
            {
              return (-1);
            }
          jtl->hinsi[jtl->maxserial] = SAKUJO_HINSI;
          jtl->ri2[jtl->maxserial].kanjipter = 0xffffffff;
          jtl->ri2[jtl->maxserial].next[D_YOMI] = jtl->ri2[jtl->maxserial].next[D_KANJI] = RD_ENDPTR;
          jtl->maxserial++;
          jtl->maxri2++;
        }
    }
  return (0);

#ifdef nodef
/*    UCHAR *c, *c0; */
/*      int kan, len; */
  if (p->kosuu == 1)
    {
      Get_kanji (p->kanjipter + jtl->kanji, yomi, Strlen (yomi), kanji, NULL, NULL);
      if ((jtl->bufsize_kanji <= jtl->maxkanji + (Strlen (kanji) + Strlen (comment)) * sizeof (w_char) + 4)
	  && (ud_realloc_kanji (jtl) == NULL))
        {
          return (-1);
        }
      if (p->kanjipter + *(p->kanjipter + jtl->kanji) >= jtl->maxkanji)
        {
          jtl->maxkanji = p->kanjipter;
        }
      p->kanjipter = jtl->maxkanji;
      kanjiadd (jtl, kanji, yomi, comment);
    }
  else
    {
      /*nagasa wo hakatte realloc */
      for (k = 0, c = p->kanjipter + jtl->kanji; k < p->kosuu; k++)
        c += *c;
      len = c - (p->kanjipter + jtl->kanji);
      while (jtl->bufsize_kanji <= jtl->maxkanji + (Strlen (kanji) + Strlen (comment)) * sizeof (w_char) + 4 + len)
        {
          if (ud_realloc_kanji (jtl) == NULL)
            {
              return (-1);
            }
        }
      if (p->kanjipter + len >= jtl->maxkanji)
        {
          jtl->maxkanji = p->kanjipter;
        }
      kan = jtl->maxkanji;

      /*mae made no nagasa wo hakatte bcopy */
      for (k = 0, c = p->kanjipter + jtl->kanji; k < serial - p->serial; k++)
        {
          c += *c;
        }
      len = c - (p->kanjipter + jtl->kanji);
      bcopy (p->kanjipter + jtl->kanji, jtl->maxkanji + jtl->kanji, len);

      jtl->maxkanji += len;
      Get_kanji (c, yomi, Strlen (yomi), kanji, NULL, NULL);
      kanjiadd (jtl, kanji, yomi, comment);
      c += *c;

      c0 = c;
      for (k = serial + 1, c = p->kanjipter + jtl->kanji; k < p->kosuu + p->serial; k++)
        {
          c += *c;
        }
      len = c - c0;
      bcopy (c0, jtl->maxkanji + jtl->kanji, len);
      jtl->maxkanji += len;
      p->kanjipter = kan;
    }
  return (0);
#endif
}


int
hindo_file_size_justify (wfp, whfp)
     struct wnn_file *wfp, *whfp;
{
  struct HJT *hjtp;
  struct JT *jtp;
  int k;

  jtp = (struct JT *) (wfp->area);
  hjtp = (struct HJT *) (whfp->area);

  if (hjtp->maxserial != jtp->maxserial)
    {
      if (hjtp->maxserial < jtp->maxserial)
        {
          while (hjtp->bufsize_serial <= jtp->maxserial)
            {
              if (hindo_file_realloc (hjtp) == 0)
                return (-1);
            }
          error1 ("Dic file size is bigger than that of Hindo file!");
          for (k = hjtp->maxserial; k < jtp->maxserial; k++)
            {
              hjtp->hindo[k] = 0;
            }
        }
      else
        {
          error1 ("Hindo file size is bigger than that of Dic file!");
        }
      hjtp->maxserial = jtp->maxserial;
      hjtp->hdirty = 1;
    }
  return (0);
}
