/* 
 * $Id: hdr_build.c,v 1.17 1999/02/18 15:39:49 gerald Exp $
 */

/*
 * All the routines in this module are designed to
 * build the header information that is used in
 * the pipeline communication between modules.
 *
 * Header structure:
 *
 * ... fill in when completely specified
 */

#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <mrt.h>
#include <irr_check.h>


void convert_toupper (char *_z) {

  while (*_z != '\0') {
    *_z = toupper(*_z);
    _z++;
  }
}

void convert_tolower (char *_z) {

  while (*_z != '\0') {
    *_z = tolower(*_z);
    _z++;
  }
}

char *get_header_token (parse_info_t *obj, int toupper, int make_space) {
  char *token, *p = NULL;
  int i;

  first_token (token);
  for (i = obj->field_count; i > 0; i--) {
    if (toupper)
      convert_toupper(token);
    p = my_concat (p, token, make_space);
    next_token (token);
  }

  return p;
}
 
/* This routine concat's x and y, putting a space
 * beteen x and y.  It assumes that the
 * caller is placing the result in x, so the routine
 * free's x if it points to something.
 * 
 * The calling convention should be like this:
 * x = myconcat (x, y);
 *   x and/or y may be NULL and routine will work.
 */
char *my_concat (char *x, char *y, int make_space) {
  char buf[MAXLINE];

  if (x == NULL)
    buf[0] = '\0';
  else {
    strcpy (buf, x);
    free (x);
  }

  if (y != NULL) {
    if (buf[0] != '\0' && make_space)
      strcat (buf, " ");

    strcat (buf, y);
  }

  if (buf[0] == '\0')
    return NULL;
  else
    return strdup (buf);
}


char *get_header_list_attr (parse_info_t *obj, char *list_attr, int toupper) {
  char *p, *x;

  if ((p = get_header_token (obj, toupper, 1)) == NULL)
    return NULL;

  x = my_concat (list_attr, p, 1);
  free (p);
  return x;
}

/*
void print_header_field (char *hdr, char *hdr_info) {

  printf ("%s", hdr);
  if (hdr_info != NULL)
    printf (" %s", hdr_info);
  printf ("\n");
}
*/

void display_header_info (parse_info_t *hi) {
  fprintf (ofile, "%s\n", HDR_START);

  if (hi->errors)
    fprintf (ofile, "%s\n", SYNTAX_ERRORS);
  else if (hi->warns)
    fprintf (ofile, "%s\n", SYNTAX_WARNS);

  if (hi->type != NO_OBJECT)
    fprintf (ofile, "%s%s\n", OBJ_TYPE, obj_type[hi->type]);

  if (hi->obj_key != NULL) {
    fprintf (ofile, "%s%s", OBJ_KEY, hi->obj_key);
    if (hi->second_key != NULL)
      fprintf (ofile, " %s", hi->second_key);
    fprintf (ofile, "\n");
  }

  if (hi->op != NULL)
    fprintf (ofile, "%s%s\n", OP, hi->op);

  if (hi->source != NULL)
    fprintf (ofile, "%s %s\n", SOURCE, hi->source);

  if (hi->mnt_by != NULL)
    fprintf (ofile, "%s %s\n", MNT_BY, hi->mnt_by);

  if (hi->override != NULL)
    fprintf (ofile, "%s %s\n", OVERRIDE, hi->override);

  if (hi->password != NULL)
    fprintf (ofile, "%s %s\n", PASSWORD, hi->password);

  if (hi->check_notify != NULL)
    fprintf (ofile, "%s %s\n", CHECK_NOTIFY, hi->check_notify);

  if (hi->check_mnt_nfy != NULL)
    fprintf (ofile, "%s %s\n", CHECK_MNT_NFY, hi->check_mnt_nfy);

  if (hi->cookies != NULL)
    fprintf (ofile, "%s", hi->cookies);


  fprintf (ofile, "%s\n", HDR_END);
}


void build_header_info (parse_info_t *obj) {

  if (obj->obj_key == NULL   &&
      obj->type != NO_OBJECT &&
      obj->curr_attr >= 0    &&
      attr_is_key[obj->curr_attr] >= 0) {
    if (obj->curr_attr == F_IR)
      obj->obj_key = get_header_token (obj, 0, 0);
    else
      obj->obj_key = get_header_token (obj, 1, 1);
  }
  
  if ((obj->curr_attr == F_OR  ||
       obj->curr_attr == F_NH) &&
      obj->second_key == NULL)
    obj->second_key = get_header_token (obj, 1, 1);
  
  if (obj->curr_attr == F_SO &&
      obj->source == NULL)
    obj->source = get_header_token (obj, 1, 1);
  
  if (obj->curr_attr == F_MB)
    obj->mnt_by = get_header_list_attr (obj, obj->mnt_by, 1);

  if (obj->curr_attr == F_NY)
    obj->check_notify = get_header_list_attr (obj, obj->check_notify, 0);

  if (obj->curr_attr == F_MN)
    obj->check_mnt_nfy = get_header_list_attr (obj, obj->check_mnt_nfy, 0);

}
