# include "fits.h"

int fits_scan (Header *header, char *field, char *mode, int N,...) {

  int status;
  va_list argp;
  
  va_start (argp, N);
  status = fits_vscan (header, field, mode, N, argp);
  va_end (argp);
  return (status);
}
  
int fits_vscan (Header *header, char *field, char *mode, int N, va_list argp) {

  char *p, *q, tmp[81];
  int Nchar;
  double value;
  
  /* find the correct line with field */
  p = fits_header_field (header, field, N);
  if (p == NULL) return (FALSE);

  /* non-data entry (COMMENT, HISTORY) */
  if (!strcmp (mode, "%S")) {
    strncpy (va_arg (argp, char *), p + 8, FT_HISTORY_LENGTH);
    goto gotvalue;
  }

  /* all others require '=' in column 8 */
  if (p[8] != '=') return (FALSE);

  /* comment from data line */
  if (!strcmp (mode, "%C")) {
    q = fits_keyword_end (p) + 3;
    q = MIN (p + 80, q);
    bzero (tmp, 81);
    Nchar = MIN (80, p + 80 - q);
    memcpy (tmp, q, Nchar);
    fits_stripwhite (tmp);
    strcpy (va_arg (argp, char *), tmp);
    goto gotvalue;
  }

  /* extract data into char array (exclude containing ' chars) */
  if (!strcmp (mode, "%s")) {
    q = fits_keyword_end (p);
    q -= 1;
    p += 10;

    /* exclude containing ' chars, if they exist */
    /* we are not requiring a string entry to have the quotes */
    if (*p == 0x27) p++;
    if (*q == 0x27) q--;

    Nchar = MAX (0, (q - p + 1));
    bzero (tmp, 81);
    memcpy (tmp, p, Nchar);
    fits_stripwhite (tmp);
    strcpy (va_arg (argp, char *), tmp);
    goto gotvalue;
  }
  
  /* boolean data, requires int target */
  if (!strcmp (mode, "%t")) {
    if (p[29]  == 'T') 
      *va_arg (argp, int *) = TRUE;
    if (p[29]  == 'F') 
      *va_arg (argp, int *) = FALSE;   
    goto gotvalue;
  }

  /* remaining options are numerical data */
  /* need to interpret 1.0d5 as 1.0e5 */
  value = strtod (p + 10, &q);
  if ((*q == 'd') || (*q == 'D')) 
    value *= pow (10.0, atof (q + 1));

  if (!strcmp (mode, "%d"))  { *va_arg (argp, int *)       = value; goto gotvalue; }
  if (!strcmp (mode, "%u"))  { *va_arg (argp, unsigned *)  = value; goto gotvalue; }
  if (!strcmp (mode, "%ld")) { *va_arg (argp, long *)      = value; goto gotvalue; }
  if (!strcmp (mode, "%hd")) { *va_arg (argp, short *)     = value; goto gotvalue; }
  if (!strcmp (mode, "%f"))  { *va_arg (argp, float *)     = value; goto gotvalue; }
  if (!strcmp (mode, "%lf")) { *va_arg (argp, double *)    = value; goto gotvalue; }

  /* no valid mode found */
  return (FALSE);

 gotvalue:
  return (TRUE);
}

/* if the variable argument stuff breaks on another system, look 
at F_modify.c as it has the old code */

#ifndef whitespace
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif

/* Strip whitespace from the start and end of STRING. */
int fits_stripwhite (char *string) {

  int i;

  if (string == (char *) NULL)
    return (FALSE);

  for (i = 0; whitespace (string[i]); i++);
  if (i) memmove (string, string + i, strlen(string+i)+1);
  for (i = strlen (string) - 1; (i > 0) && whitespace (string[i]); i--);
  string[++i] = 0;

  return (i);

}

# if (0)
    one_quote = FALSE;
    tmp[0] = *(p + 10);
    if (tmp[0] == 0x27)
      one_quote = TRUE;
    /* end the string if we hit: a -- end of line (80 chars) b -- NEWLINE c -- '(0x27: single quote) (end of string) */
    for (i = 1; (i < 70) && (p[i + 10] != NEWLINE) && ((p[i + 10] != 0x27) || !one_quote); i++) {
      tmp[i] = *(p + 10 + i);
      if ((tmp[i] == 0x27) && !one_quote)
	one_quote = TRUE;
      if ((tmp[i] == 0x2f) && !one_quote)
	break;
    }
    tmp[i] = 0;
    if ((c = strchr (tmp, 0x27)) != NULL)
      *c = ' ';
# endif
