/* ------------------------------------------------------------------- */
/* util      : Several utilities for the d2m converter                 */
/*                                                                     */
/* Author    : Ole Husby                                               */
/* Updated   : 1998-09-30                                              */
/* ------------------------------------------------------------------- */


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




/* ------------------------------------------------------------------- */
/* Produce MARC line-format output                                     */
/* ------------------------------------------------------------------- */

void write_field(char *l, FILE *of, int linel, int llen, int slen)
{
  char pre[64], line[256], *p, *q, *n;
  int more, i, spos, compact, ctr;

  ctr = 0;
  *pre = *line = 0;
  p = strdup(l);
  q = p;

  more = TRUE;
  compact = FALSE;  

  while (more)
  {

    ctr++;
    if (ctr > 20) more = FALSE;

    if (strlen(q) <= linel - 8)           /* String fits into 1 line  */
    {
      if (compact)
      {
        fprintf(of, "%s%s\n", pre, q);
        more = FALSE;
      }
      else
      {
        n = strstr(q + 6, "$");

        if ( (n - q ) > 5)
        {
          spos = (n - q);
          strncat(line, q, spos);
          q = n;
          fprintf(of, "%s%s\n", pre, line);
          strcpy(pre, "     ");
          *line = 0;
        }
        else
        {
          fprintf(of, "%s%s\n", pre, q);
          more = FALSE;
        }
      }
    }

    else                                  /* Look for splitting point */
    {
      spos = 0;

      if (!compact)
      {
        for (i = 6; i < linel - 8; i++)
        {
          if (q[i] == '$')
          {
            spos = i + 1;
            break;
          }
        } 
      }

 
      if (!spos)
      {
        for (i = linel - 9; i > slen; i--)
        {
          if ( !compact && (q[i] == '$'))
          {
            spos = i + 1;
            break;
          }
          else if (q[i] == ' ')
          {
            spos = i;
            break;
          }
        }
      }

      if (spos)
      {
         strncat(line, q, spos);
         q +=  spos + 1;
      }
      else
      {
         strncat(line, q, llen);
         strcat(line, "-");
         q += llen;
      }

      fprintf(of, "%s%s\n", pre, line);
      strcpy(pre, "     ");
      *line = 0;
    }
  }
  free(p);
}



/* ------------------------------------------------------------------- */
/* Fetching HTTP POST data                                             */
/* ------------------------------------------------------------------- */

char *poq() 
{
    int m=0, c, cl;
    char *rec;

    if(strcmp(getenv("REQUEST_METHOD"),"POST"))
      return NULL;

    cl = atoi(getenv("CONTENT_LENGTH"));

    if (cl)
      rec = (char*) malloc(cl + 1);
    else
      return NULL;
    
    while (c = fgetc(stdin))
    {
      rec[m] = c;
      m++;
      if (m >= cl) break;
    }

    rec[m] = 0;

    return rec;
}



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

int unesc (char h, char l)
{
   char buf[3];
   int i;

   buf[0]=h;
   buf[1]=l;
   buf[2]='\0';
   sscanf(buf,"%x",&i);
   return (i);
}


/* ------------------------------------------------------------------- */
/* Replace '+' with space and unescape hex coded characters.           */
/* ------------------------------------------------------------------- */

void unescape (char *s)
{
   char *rp, *wp;  /* read position and write position in string */
   rp=wp=s;
   while (*rp != '\0') {
      if (*rp=='+') {
         *(wp++)=' ';
         rp++;
      }
      else if (*rp=='%') {
         int a,b;
         rp++;   /* skip the '%' */
         a = (unsigned char) *(rp++);
         b = (unsigned char) *(rp++);
         *(wp++)=unesc (a,b);
      } else
         *(wp++)=*(rp++);
    }
    *wp = '\0';
}



/* ------------------------------------------------------------------- */
/* Case independent string search.                                     */
/*                                                                     */
/* Call syntax like strstr()                                           */
/* ------------------------------------------------------------------- */

char *cstr(char *h, char *n)
{
  char *nn;
  char *hh;
  char *p, *s;
  long i;


/* Returns NULL if either of strings are NULL                     */

  if (!*h || !*n)
    return (char *) NULL;


/* Make a copy hh of h and nn of n                                */

  hh = (char *) strdup(h);
  nn = (char *) strdup(n);

/* Converts hh and nn to lower                                    */

  for (i = 0; i < strlen(nn); i++)
    nn[i] = tolower(n[i]);

  for (i = 0; i < strlen(hh); i++)
    hh[i] = tolower(h[i]);

/* Searches for nn in hh using strstr                             */

  p = (char *) strstr(hh, nn);

/* If found, calculates corresponding pointer into h              */

  if (!p)
    s = (char *) NULL;
  else
  {
    i = strlen(hh) - strlen(p);
    s = h + i;
  }

/* Frees string copies and returns                                */

  free(hh);
  free(nn);

  return s; 
}



/* ------------------------------------------------------------------- */
/* Write and remove tracefile                                          */
/* ------------------------------------------------------------------- */

int write_trace(char *tracefile, FILE *of)
{
  char line[10000], *l;
  FILE *tf;

  tf = fopen(tracefile, "r");
  if (!tf)
    return 0;

  while (l = fgets(line, 9999, tf))
    fprintf(of, "%s", l);

  fclose(tf);
  remove(tracefile);  
  return 1;
}


/* ------------------------------------------------------------------- */
/* Insert field into 008                                               */
/* ------------------------------------------------------------------- */

int put008(char *s8, char *str, int f8)
{
   int i, len, pos, nlen, npos, append=0;

   if (strlen(s8) != 40)
     return 0;

   switch (f8)
   {
     case (F008_DATE_ENTERED) :
     {
       pos = 0;
       len = 6;
       break;
     }
     case (F008_TYPE_OF_DATE) :
     {
       pos = 6;
       len = 1;
       break;
     }
     case (F008_DATE1) :
     {
       pos = 7;
       len = 4;
       break;
     }
     case (F008_FORM_OF_PUBLICATION) :
     {
       pos = 24;
       len = 4;
       append = 1;
       break;
     }
     case (F008_LANGUAGE) :
     {
       pos = 35;
       len = 3;
       break;
     }
     default :
       return 0;
   }


   npos = pos;
   nlen = strlen(str);
   if (nlen > len)
     return 0;

   if (nlen < len)
   {
     if (append)
     {
       npos = 0;
       for (i = pos; i < pos + len; i++)
       {
         if ( s8[i] == ' ' )
         {
           npos = i;
           break; 
         }
       }
       if (npos == 0)
         return 0;
       if (npos >= pos + len)
         return 0;
       if (npos + nlen > pos + len)
         return 0;
     }
     else
       return 0;
   }
/* printf
     ("pos %d len %d npos %d nlen %d str %s\n", 
     pos, len, npos, nlen, str);
*/

   for (i = 0; i < nlen; i++)
     s8[npos+i] = str[i];

   return 1;
}


/* ------------------------------------------------------------------- */
/* Converts date to YYYY                                               */
/* ------------------------------------------------------------------- */

int find_year(char *str)
{
  int i;

  if (strlen(str) < 4)
    return 0;

  str[4] = 0;

  for (i = 0; i < 4; i++)
  {
    if (!isdigit(str[i]))
      return 0;
  }
 
  return 1;
}




/* ------------------------------------------------------------------- */
/* Splits personal name at first "," into $a and $h                    */
/* ------------------------------------------------------------------- */

int split_name(char *str)
{
  char *p, *q, subtag[5];

  if (!strstr(str, ","))
    return 1;

  p = (char *) malloc(strlen(str) + 50);
  *p = 0;
  *subtag = 0;

  q = strtok(str, ",");
  if (q)
  {
    strcpy(p, q);
    q = strtok(NULL, "\0");
    if (q)
    {
      while ( ( q[0] == ' ' ) && ( strlen(q) ) )
        q++;
      strcat(p, " $h ");
      strcat(p, q);
    }
    strcpy(str, p);
  }

  free(p);

  return 1;
}



/* ------------------------------------------------------------------- */
/* Splits subject heading on "-". First occurence go into $a, second   */ 
/* into $b, all the rest into $x                                       */
/* ------------------------------------------------------------------- */

int split_subj(char *str)
{
  char *p, *q, subtag[5];

  if (!strstr(str, "-"))
    return 1;

  p = (char *) malloc(strlen(str) + 50);
  *p = 0;
  *subtag = 0;

  q = strtok(str, "-");
  while (q)
  {
    while ( ( q[0] == ' ' ) && ( strlen(q) ) )
      q++;

    while( ( q[strlen(q) - 1] == ' ' ) && ( strlen(q) ) )
      q[strlen(q) - 1] = '\0';

    if (*q)
    {
      strcat(p, subtag);
      strcat(p, q);
      if (!*subtag)
        strcpy(subtag, " $b ");
      else
        strcpy(subtag, " $x ");
    }
    q = strtok(NULL, "-");
  }

  strcpy(str, p);
  free(p);

  return 1;
}
