/* Read a range from file f.
   Returns 1 if successful, with pmin and pmax modified.
   Throws an error if the range is invalid.
   Returns 0 if otherwise (EOF), with pmin and pmax unmodified.
 */
static int read_range(uint64_t *pmin, uint64_t *pmax, FILE *f, const char *fn)
{
  uint64_t p[2];
  const char *fmt_p[2] = { "pmin=%"SCNu64, "pmax=%"SCNu64 };
  const char *line;
  int next; /* 0 = min, 1 = max */

  if ((line = read_line(f)) == NULL)
    return 0;
  if (sscanf(line,fmt_p[0],&p[0]) == 1)
    next = 1;
  else if (sscanf(line,fmt_p[1],&p[1]) == 1)
    next = 0;
  else
    line_error("Unparsed range",NULL,fn);

  if ((line = read_line(f)) == NULL)
    line_error("Incomplete range",NULL,fn);
  if (sscanf(line,fmt_p[next],&p[next]) != 1)
    line_error("Unparsed range",NULL,fn);

  if (p[0] >= p[1])
    line_error("Invalid range",NULL,fn);

  *pmin = p[0];
  *pmax = p[1];

  return 1;
}
Пример #2
0
static int read_candidate_seq_file(const char *file_name)
{
  FILE *file;
  const char *line;
  uint32_t k_count;

  file = xfopen(file_name, "r", error);
  for (k_count = 0; (line = read_line(file)) != NULL; k_count++)
    if (parse_seq_str(line,file_name) == UINT32_MAX)
    {
      if (k_count == 0)
      {
        fclose(file);
        return 0;
      }
      else
        line_error("Malformed line","candidate sequence",file_name);
    }

  if (ferror(file))
    line_error("Read error","candidate sequence",file_name);
  fclose(file);
  report("Read %"PRIu32" sequence%s from input file `%s'.",
         k_count, plural(k_count), file_name);

  return 1;
}
Пример #3
0
void	check_cmd_hex(t_cmd *cmd, op_t *op)
{
  int	i;

  cmd->byte = 1;
  cmd->cmd_hex[0] = op->code;
  if (op->cbyte == 1)
  {
    cmd->cmd_hex[cmd->byte] = get_cbyte(cmd->arg, cmd->line);
    cmd->byte++;
  }
  i = 0;
  while (cmd->arg[i] != NULL)
    i++;
  if (i < op->nbr_args)
    line_error(ARG_INF_ERROR, cmd->line, 1);
  else if (i > op->nbr_args)
    line_error(ARG_SUP_ERROR, cmd->line, 1);
  i = 0;
  while (cmd->arg[i] != NULL)
  {
    if (!(get_type(cmd->arg[i]) & op->type_i[i]))
      line_error(ARG_ERROR, cmd->line, 1);
    i++;
  }
}
Пример #4
0
/* This function cannot parse a general ABCD format file, only the specific
   type (ABCD k*b^n+c with fixed k,b,c and variable n) written by srsieve.
*/
static int read_abcd_file(const char *file_name)
{
  FILE *file;
  const char *line;
  uint64_t k, p_start;
  int64_t c;
  uint32_t seq, n, delta, b, n_count, s_count;

  file = xfopen(file_name, "r", error);
  n_count = s_count = seq = n = 0;
  while ((line = read_line(file)) != NULL)
  {
    if (sscanf(line, "%" SCNu32, &delta) == 1)
    {
      if (s_count == 0)
      {
        fclose(file);
        return 0;
      }
      n += delta;
      add_seq_n(seq,n);
      n_count++;
    }
    else
      switch (sscanf(line, "ABCD %" SCNu64 "*%" SCNu32 "^$a%" SCNd64
                     " [%" SCNu32 "] // Sieved to %" SCNu64,
                     &k, &b, &c, &n, &p_start))
      {
        case 5:
          set_p_min(p_start,file_name);
          /* fall through */

        case 4:
          check_and_set_base(b,file_name);
          seq = get_seq(k,c);
          s_count++;
          add_seq_n(seq,n);
          n_count++;
          break;

        default:
          if (s_count == 0)
          {
            fclose(file);
            return 0;
          }
          else
            line_error("Malformed line","ABCD",file_name);
      }
  }

  if (ferror(file))
    line_error("Read error","ABCD",file_name);
  fclose(file);
  report_read(n_count,s_count,"ABCD",file_name);

  return 1;
}
Пример #5
0
static int read_newpgen_file(const char *file_name)
{
  FILE *file;
  const char *line;
  char mode_char;
  int mode_bits, type;
  uint32_t b, n_count, n, old_count, seq;
  uint64_t k, p_start;

  /* Try to read header */
  file = xfopen(file_name, "r", error);
  line = read_line(file);
  /* headers are of the form <p_start>:<mode_char>:<int>:<base>:<mode_bits>
   */
  if (sscanf(line, "%" SCNu64 ":%c:%*d:%" SCNu32 ":%d",
             &p_start, &mode_char, &b, &mode_bits) != 4)
  {
    fclose(file);
    return 0;
  }

  check_and_set_base(b,file_name);
  set_p_min(p_start,file_name);

  if (mode_char == 'P' && mode_bits == 257)
    type = 16;
  else if (mode_char == 'M' && mode_bits == 258)
    type = 17;
  else if (mode_char == 'P' && mode_bits == 32769)
    type = 19;
  else if (mode_char == 'M' && mode_bits == 32770)
    type = 20;
  else
    line_error("Unrecognised sieve type","NewPGen",file_name);

  old_count = seq_count;
  for (n_count = 0; (line = read_line(file)) != NULL; n_count++)
  {
    if (sscanf(line, "%" SCNu64 " %" SCNu32, &k, &n) != 2)
      line_error("Malformed line","NewPGen",file_name);
    switch (type)
    {
      case 16: seq = get_seq(k,1); break;
      case 17: seq = get_seq(k,-1); break;
      case 19: seq = get_seq(1,k); break;
      case 20: default: seq = get_seq(1,-k); break;
    }
    add_seq_n(seq,n);
  }

  if (ferror(file))
    line_error("Read error","NewPGen",file_name);
  fclose(file);
  report_read(n_count,seq_count-old_count,"NewPGen",file_name);

  return 1;
}
Пример #6
0
static int read_pfgw_file(const char *file_name)
{
  FILE *file;
  const char *line;
  uint64_t p, k;
  int64_t c;
  uint32_t b, n_count, n, old_count;
  char c1, c2, c3;

  /*
    ABC $a*<base>^$b$c (or ABC $a*<base>^$b+$c)
    k n c
    k n c
  */

  file = xfopen(file_name, "r", error);
  line = read_line(file);

  /* The "%*[+$]" allows the "+" to be ignored if present, for compatibility
     with versions prior to 0.6.13.
  */
  switch (sscanf(line,"ABC $%c*%"SCNu32"^$%c%*[+$]%c // Sieved to %"SCNu64,
                 &c1,&b,&c2,&c3,&p))
  {
    case 5:
      set_p_min(p,file_name);
      /* fall through */
    case 4:
      if (c1 != 'a' || c2 != 'b' || c3 != 'c')
        line_error("Unrecognised header","abc",file_name);
      check_and_set_base(b,file_name);
      break;
    default:
      fclose(file);
      return 0;
  }

  old_count = seq_count;
  n_count = 0;
  while ((line = read_line(file)) != NULL)
  {
    if (sscanf(line, "%"SCNu64" %"SCNu32" %"SCNd64, &k, &n, &c) != 3)
      line_error("Malformed line","abc",file_name);
    add_seq_n(get_seq(k,c), n);
    n_count++;
  }

  if (ferror(file))
    line_error("Read error","abc",file_name);
  fclose(file);
  report_read(n_count,seq_count-old_count,"abc",file_name);

  return 1;
}
Пример #7
0
/* Add an entry for a function, macro, special form, variable, or option.
   If the name of the calling command ends in `x', then this is an extra
   entry included in the body of an insertion of the same type. */
void
cm_defun (void)
{
  int type;
  char *base_command = xstrdup (command);  /* command with any `x' removed */
  int x_p = (command[strlen (command) - 1] == 'x');

  if (x_p)
    base_command[strlen (base_command) - 1] = 0;

  type = find_type_from_name (base_command);

  /* If we are adding to an already existing insertion, then make sure
     that we are already in an insertion of type TYPE. */
  if (x_p)
    {
      INSERTION_ELT *i = insertion_stack;
      /* Skip over ifclear and ifset conditionals.  */
      while (i && (i->insertion == ifset || i->insertion == ifclear))
        i = i->next;
        
      if (!i || i->insertion != type)
        {
          line_error (_("Must be in `@%s' environment to use `@%s'"),
                      base_command, command);
          discard_until ("\n");
          return;
        }
    }

  defun_internal (type, x_p);
  free (base_command);
}
/* Read the range p0,p1 and checkpoint p from SoBStatus.dat.
   If no file exists or p0 != pmin or p1 != pmax, return pmin.
   If no checkpoint line exists, return pmax.
   If the range is complete, return pmax.
   Otherwise return p.
*/
uint64_t sob_read_checkpoint(uint64_t pmin, uint64_t pmax)
{
  FILE *file;
  const char *line;
  uint64_t p0, p1, p;

  p = pmin;
  if ((file = xfopen(sob_status_file_name,"r",NULL)) != NULL)
  {
    if (read_range(&p0,&p1,file,sob_status_file_name))
      if (p0 == pmin && p1 == pmax)
      {
        while ((line = read_line(file)) != NULL)
          if (sscanf(line,"pmin=%"SCNu64,&p) != 1)
            break;

        if (p < pmin || p > pmax)
          line_error("Invalid checkpoint",NULL,sob_status_file_name);

        if (line != NULL && !strncmp("Done",line,4))
          p = pmax;

        if (p > pmin && p < pmax)
          report(1,"Resuming from checkpoint pmin=%"PRIu64" in `%s'.",
                 p,sob_status_file_name);
      }
    xfclose(file,sob_status_file_name);
  }

  last_checkpoint_time = millisec_elapsed_time();
  last_checkpoint_prime = p;

  return p;
}
Пример #9
0
void
make_builtin_hooks(fcode_env_t *env, char *where)
{
	FILE *fd;
	int lnum = 0, len;
	char *buffer, *line, *target, *next;

	if (where == NULL)
		where = "/fcode/aliases";

	if ((fd = fopen(where, "r")) == NULL) {
		return;
	}

	buffer = MALLOC(PARSE_LINE+1);

	while ((line = fgets(buffer, PARSE_LINE, fd)) != NULL) {
		lnum++;
		if ((next = strpbrk(line, " \t#\n")) != NULL)
			*next = '\0';
		if (strlen(line) == 0)
			continue;
		if ((target = strchr(line, ':')) == NULL) {
			line_error(where, lnum, "Badly formed line");
			continue;
		}
		*target++ = 0;
		if (strlen(line) == 0) {
			line_error(where, lnum, "Badly formed alias");
			continue;
		}
		if (strlen(target) == 0) {
			line_error(where, lnum, "Badly formed target");
			continue;
		}
		for (; line; line = next) {
			if ((next = strchr(line, ';')) != NULL)
				*next++ = '\0';
			if (strlen(line) == 0)
				line_error(where, lnum, "Null key in alias");
			else
				define_hook(env, line, strlen(line), target);
		}
	}
	FREE(buffer);
	fclose(fd);
}
Пример #10
0
/* Returns 1 if successful, or 0 if file_name is not a srsieve format file
   (so that another file type can be tried). The srsieve file format is:

    pmin=<uint64_t>
    k*b^n+c
    n
    n
    ...
    k*b^n+c
    n
    n
    ...
*/
static int read_srsieve_file(const char *file_name)
{
  FILE *file;
  const char *line;
  uint64_t p_start;
  uint32_t seq, n, n_count, k_count;
  char ch;

  /* try to read header */
  file = xfopen(file_name, "r", error);
  line = read_line(file);
  if (line == NULL || sscanf(line, "pmin=%" SCNu64, &p_start) != 1)
  {
    fclose(file);
    return 0;
  }
  set_p_min(p_start,file_name);

  /* read sequences */
  k_count = n_count = seq = 0;
  while ((line = read_line(file)) != NULL)
  {
    if (sscanf(line, "%" SCNu32 " %c", &n, &ch) == 1)
    {
      if (k_count == 0)
        line_error("Missing sequence header","srsieve",file_name);
      add_seq_n(seq,n);
      n_count++;
    }
    else if ((seq = parse_seq_str(line,file_name)) < UINT32_MAX)
      k_count++;
    else
      line_error("Malformed line","srsieve",file_name);
  }

  if (ferror(file))
    line_error("Read error","srsieve",file_name);
  fclose(file);
  report_read(n_count,k_count,"srsieve",file_name);

  return 1;
}
Пример #11
0
void
cm_footnotestyle (void)
{
  char *arg;

  get_rest_of_line (1, &arg);

  /* If set on command line, do not change the footnote style.  */
  if (!footnote_style_preset && set_footnote_style (arg) != 0)
    line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command);

  free (arg);
}
Пример #12
0
void		create_cmd_hex(t_list *list)
{
  int		i;
  t_cmd		*cmd;
  op_t		*op;

  i = 0;
  while (i < list->nb_elm)
  {
    cmd = get_data(list, i);
    if ((op = get_op(cmd->mne)) == NULL)
      line_error(MNE_ERROR, cmd->line, 1);
    cmd->op = op;
    check_cmd_hex(cmd, op);
    fill_cmd_hex(cmd, op);
    i++;
  }
}
Пример #13
0
/* Given STRING_POINTER pointing at an open brace, skip forward and return a
   pointer to just past the matching close brace. */
static int
scan_group_in_string (char **string_pointer)
{
  char *scan_string = (*string_pointer) + 1;
  unsigned int level = 1;
  int started_command = 0;

  for (;;)
    {
      int c;
      if (level == 0)
        {
          *string_pointer = scan_string;
          return 1;
        }
      c = *scan_string++;
      if (c == 0)
        {
          /* Tweak line_number to compensate for fact that
             we gobbled the whole line before coming here. */
          line_number--;
          line_error (_("Missing `}' in @def arg"));
          line_number++;
          *string_pointer = scan_string - 1;
          return 0;
        }

      if (c == '{' && !started_command)
        level++;
      if (c == '}' && !started_command)
        level--;

      /* remember if at @.  */
      started_command = (c == '@' && !started_command);
    }
}
Пример #14
0
 /* Handle a "footnote".
    footnote *{this is a footnote}
    where "*" is the (optional) marker character for this note. */
void
cm_footnote (void)
{
  char *marker;
  char *note;

  get_until ("{", &marker);
  canon_white (marker);

  if (macro_expansion_output_stream && !executing_string)
    append_to_expansion_output (input_text_offset + 1); /* include the { */

  /* Read the argument in braces. */
  if (curchar () != '{')
    {
      line_error (_("`%c%s' needs an argument `{...}', not just `%s'"),
                  COMMAND_PREFIX, command, marker);
      free (marker);
      return;
    }
  else
    {
      int len;
      int braces = 1;
      int loc = ++input_text_offset;

      while (braces)
        {
          if (loc == input_text_length)
            {
              line_error (_("No closing brace for footnote `%s'"), marker);
              return;
            }

          if (input_text[loc] == '{')
            braces++;
          else if (input_text[loc] == '}')
            braces--;
          else if (input_text[loc] == '\n')
            line_number++;

          loc++;
        }

      len = (loc - input_text_offset) - 1;
      note = xmalloc (len + 1);
      memcpy (note, &input_text[input_text_offset], len);
      note[len] = 0;
      input_text_offset = loc;
    }

  /* Must write the macro-expanded argument to the macro expansion
     output stream.  This is like the case in index_add_arg.  */
  if (macro_expansion_output_stream && !executing_string)
    {
      /* Calling me_execute_string on a lone } provokes an error, since
         as far as the reader knows there is no matching {.  We wrote
         the { above in the call to append_to_expansion_output. */
      me_execute_string_keep_state (note, "}");
    }

  if (!current_node || !*current_node)
    {
      line_error (_("Footnote defined without parent node"));
      free (marker);
      free (note);
      return;
    }

  /* output_pending_notes is non-reentrant (it uses a global data
     structure pending_notes, which it frees before it returns), and
     TeX doesn't grok footnotes inside footnotes anyway.  Disallow
     that.  */
  if (already_outputting_pending_notes)
    {
      line_error (_("Footnotes inside footnotes are not allowed"));
      free (marker);
      free (note);
      return;
    }

  if (!*marker)
    {
      free (marker);

      if (number_footnotes)
        {
          marker = xmalloc (10);
          sprintf (marker, "%d", current_footnote_number);
        }
      else
        marker = xstrdup ("*");
    }

  if (xml)
    xml_insert_footnote (note);
  else 
    {
  remember_note (marker, note);

  /* fixme: html: footnote processing needs work; we currently ignore
     the style requested; we could clash with a node name of the form
     `fn-<n>', though that's unlikely. */
  if (html)
    {
      /* Hyperlink also serves as an anchor (mnemonic: fnd is footnote
         definition.)  */
      add_html_elt ("<a rel=\"footnote\" href=");
      add_word_args ("\"#fn-%d\" name=\"fnd-%d\"><sup>%s</sup></a>",
		     current_footnote_number, current_footnote_number,
                     marker);
    }
  else
    /* Your method should at least insert MARKER. */
    switch (footnote_style)
      {
      case separate_node:
        add_word_args ("(%s)", marker);
        execute_string (" (*note %s-Footnote-%d::)",
                        current_node, current_footnote_number);
        if (first_footnote_this_node)
          {
            char *temp_string, *expanded_ref;

            temp_string = xmalloc (strlen (current_node)
                                   + strlen ("-Footnotes") + 1);

            strcpy (temp_string, current_node);
            strcat (temp_string, "-Footnotes");
            expanded_ref = expansion (temp_string, 0);
            remember_node_reference (expanded_ref, line_number,
                                     followed_reference);
            free (temp_string);
            free (expanded_ref);
            first_footnote_this_node = 0;
          }
        break;

      case end_node:
        add_word_args ("(%s)", marker);
        break;

      default:
        break;
      }
  current_footnote_number++;
    }
  free (marker);
  free (note);
}
Пример #15
0
static void
dump_data (char **fields, FILE *stream)
{
  register int i;
  int num_fields = array_len (fields);
  BPRINTF_BUFFER *buffer = bprintf_create_buffer ();
  static int times_called = 0;
  static int offsets_calculated = 0;
  static int *key_indices = (int *)NULL;
  static int num_key_fields = 0;

  /* Get the key for this data. */
  if (!offsets_calculated)
    {
      register int j;

      offsets_calculated++;

      if (key_fields != (char **)NULL)
	{
	  int keys_matched = 0;

	  num_key_fields = array_len (key_fields);
	  key_indices = (int *)xmalloc
	    ((1 + array_len (key_fields)) * sizeof (int));

	  for (j = 0; key_fields[j] != (char *)NULL; j++)
	    {
	      for (i = 0; record_template[i] != (char *)NULL; i++)
		if (strcasecmp (record_template[i], key_fields[j]) == 0)
		  {
		    key_indices[j] = i;
		    keys_matched++;
		    break;
		  }
	      if (!record_template[i])
		break;
	    }

	  if (keys_matched != num_key_fields)
	    {
	      fprintf
		(stderr, "Warning: KeyField value (%s) not found in Template.",
		 key_fields[j]);
	      exit (2);
	    }
	}
      else
	{
	  fprintf (stderr,
		   "Warning: KeyField value not specified.  Using `%s'.\n",
		   record_template[0]);
	  num_key_fields = 1;
	  key_indices = (int *)xmalloc (2 * sizeof (int));
	  key_indices[0] = 0;
	  key_fields = (char **)xmalloc (2 * sizeof (char *));
	}
    }

  bprintf (buffer, "(\"");
  for (i = 0; i < num_key_fields; i++)
    {
      if (key_indices[i] >= num_fields)
	{
	  line_error ("Record missing required key field (%s) offset (%d)",
		      key_fields[i], key_indices[i]);
	  bprintf_free_buffer (buffer);
	  return;
	}
      else
	{
	  bprintf (buffer, "%s", fields[key_indices[i]]);
	}
    }

  times_called++;

  if (key_unique_p)
    {
      time_t ticks = (time_t)time ((time_t *)0);
      char *time_string = strdup ((char *)ctime (&ticks));

      time_string[24] = '\0'; 
      bprintf (buffer, "-%s-%d", time_string, times_called);
    }

  if (key_has_pid_p)
    {
      pid_t pid = getpid ();
      bprintf (buffer, ":%d", (int) pid);
    }

  bprintf (buffer, "\" (");

  for (i = 0; record_template[i]; i++)
    bprintf (buffer, "(\"%s\" . \"%s\")",
	     record_template[i], (i < num_fields) ? fields[i] : "");

  /* Now add any fields which were forced. */
  for (i = 0; i < forced_fields_index; i++)
    bprintf (buffer, "(\"%s\" . \"%s\")",
	     forced_fields[i]->field, forced_fields[i]->value);

  fprintf (stream, "%s))", buffer->buffer);
  bprintf_free_buffer (buffer);
}
Пример #16
0
void
cm_inforef (int arg)
{
  if (arg == START)
    {
      char *node = get_xref_token (1); /* expands all macros in inforef */
      char *pname = get_xref_token (0);
      char *file = get_xref_token (0);

      /* (see comments at cm_xref).  */
      if (!*node)
        line_error (_("First argument to @inforef may not be empty"));

      if (xml && !docbook)
        {
          xml_insert_element (INFOREF, START);
          xml_insert_element (INFOREFNODENAME, START);
          execute_string ("%s", node);
          xml_insert_element (INFOREFNODENAME, END);
          if (*pname)
            {
              xml_insert_element (INFOREFREFNAME, START);
              execute_string ("%s", pname);
              xml_insert_element (INFOREFREFNAME, END);
            }
          xml_insert_element (INFOREFINFONAME, START);
          execute_string ("%s", file);
          xml_insert_element (INFOREFINFONAME, END);

          xml_insert_element (INFOREF, END);
        }
      else if (html)
        {
          char *tem;

          add_word ((char *) _("see "));
          /* html fixxme: revisit this */
          add_html_elt ("<a href=");
          if (splitting)
            execute_string ("\"../%s/", file);
          else
            execute_string ("\"%s.html", file);
          tem = expansion (node, 0);
          add_anchor_name (tem, 1);
          add_word ("\">");
          execute_string ("%s", *pname ? pname : tem);
          add_word ("</a>");
          free (tem);
        }
      else
        {
          if (*pname)
            execute_string ("*note %s: (%s)%s", pname, file, node);
          else
            execute_string ("*note (%s)%s::", file, node);
        }

      free (node);
      free (pname);
      free (file);
    }
}
Пример #17
0
/* Make a cross reference. */
void
cm_xref (int arg)
{
  if (arg == START)
    {
      char *arg1 = get_xref_token (1); /* expands all macros in xref */
      char *arg2 = get_xref_token (0);
      char *arg3 = get_xref_token (0);
      char *arg4 = get_xref_token (0);
      char *arg5 = get_xref_token (0);
      char *tem;

      /* "@xref{,Foo,, Bar, Baz} is not valid usage of @xref.  The
         first argument must never be blank." --rms.
         We hereby comply by disallowing such constructs.  */
      if (!*arg1)
        line_error (_("First argument to cross-reference may not be empty"));

      if (docbook)
        {
          if (!ref_flag)
            add_word (px_ref_flag || printing_index
                ? (char *) _("see ") : (char *) _("See "));

          if (!*arg4 && !*arg5)
            {
              char *arg1_id = xml_id (arg1);

              if (*arg2 || *arg3)
                {
                  xml_insert_element_with_attribute (XREFNODENAME, START,
                                                     "linkend=\"%s\"", arg1_id);
                  free (arg1_id);
                  execute_string ("%s", *arg3 ? arg3 : arg2);
                  xml_insert_element (XREFNODENAME, END);
                }
              else
                {
                  xml_insert_element_with_attribute (XREF, START,
                                                     "linkend=\"%s\"", arg1_id);
                  xml_insert_element (XREF, END);
                  free (arg1_id);
                }
            }
          else if (*arg5)
            {
              add_word_args (_("See section ``%s'' in "), *arg3 ? arg3 : arg1);
              xml_insert_element (CITE, START);
              add_word (arg5);
              xml_insert_element (CITE, END);
            }
          else if (*arg4)
            {
              /* Very sad, we are losing xrefs made to ``info only'' books.  */
            }
        }
      else if (xml)
        {
          if (!ref_flag)
            add_word_args ("%s", px_ref_flag ? _("see ") : _("See "));

          xml_insert_element (XREF, START);
          xml_insert_element (XREFNODENAME, START);
          execute_string ("%s", arg1);
          xml_insert_element (XREFNODENAME, END);
          if (*arg2)
            {
              xml_insert_element (XREFINFONAME, START);
              execute_string ("%s", arg2);
              xml_insert_element (XREFINFONAME, END);
            }
          if (*arg3)
            {
              xml_insert_element (XREFPRINTEDDESC, START);
              execute_string ("%s", arg3);
              xml_insert_element (XREFPRINTEDDESC, END);
            }
          if (*arg4)
            {
              xml_insert_element (XREFINFOFILE, START);
              execute_string ("%s", arg4);
              xml_insert_element (XREFINFOFILE, END);
            }
          if (*arg5)
            {
              xml_insert_element (XREFPRINTEDNAME, START);
              execute_string ("%s", arg5);
              xml_insert_element (XREFPRINTEDNAME, END);
            }
          xml_insert_element (XREF, END);
        }
      else if (html)
        {
          if (!ref_flag)
            add_word_args ("%s", px_ref_flag ? _("see ") : _("See "));
        }
      else
        add_word_args ("%s", px_ref_flag ? "*note " : "*Note ");

      if (!xml)
        {
          if (*arg5 || *arg4)
            {
              /* arg1 - node name
                 arg2 - reference name
                 arg3 - title or topic (and reference name if arg2 is NULL)
                 arg4 - info file name
                 arg5 - printed manual title  */
              char *ref_name;

              if (!*arg2)
                {
                  if (*arg3)
                    ref_name = arg3;
                  else
                    ref_name = arg1;
                }
              else
                ref_name = arg2;

              if (html)
                { /* More to do eventually, down to Unicode
                     Normalization Form C.  See the HTML Xref nodes in
                     the manual.  */
                  char *file_arg = arg4;
                  add_html_elt ("<a href=");

                  {
                    /* If there's a directory part, ignore it.  */
                    char *p = strrchr (file_arg, '/');
                    if (p)
                      file_arg = p + 1;

                  /* If there's a dot, make it a NULL terminator, so the
                     extension does not get into the way.  */
                    p = strrchr (file_arg , '.');
                    if (p != NULL)
                      *p = 0;
                  }
                  
                  if (! *file_arg)
                warning (_("Empty file name for HTML cross reference in `%s'"),
                           arg4);

                  /* Note that if we are splitting, and the referenced
                     tag is an anchor rather than a node, we will
                     produce a reference to a file whose name is
                     derived from the anchor name.  However, only
                     nodes create files, so we are referencing a
                     non-existent file.  cm_anchor, which see, deals
                     with that problem.  */
                  if (splitting)
                    execute_string ("\"../%s/", file_arg);
                  else
                    execute_string ("\"%s.html", file_arg);
                  /* Do not collapse -- to -, etc., in references.  */
                  in_fixed_width_font++;
                  tem = expansion (arg1, 0); /* expand @-commands in node */
                  in_fixed_width_font--;
                  add_anchor_name (tem, 1);
                  free (tem);
                  add_word ("\">");
                  execute_string ("%s",ref_name);
                  add_word ("</a>");
                }
              else
                {
                  execute_string ("%s:", ref_name);
                  in_fixed_width_font++;
                  execute_string (" (%s)%s", arg4, arg1);
                  add_xref_punctuation ();
                  in_fixed_width_font--;
                }

              /* Free all of the arguments found. */
              if (arg1) free (arg1);
              if (arg2) free (arg2);
              if (arg3) free (arg3);
              if (arg4) free (arg4);
              if (arg5) free (arg5);
              return;
            }
          else
            remember_node_reference (arg1, line_number, followed_reference);

          if (*arg3)
            {
              if (html)
                {
                  add_html_elt ("<a href=\"");
                  in_fixed_width_font++;
                  tem = expansion (arg1, 0);
                  in_fixed_width_font--;
                  add_anchor_name (tem, 1);
                  free (tem);
                  add_word ("\">");
                  execute_string ("%s", *arg2 ? arg2 : arg3);
                  add_word ("</a>");
                }
              else
                {
                  execute_string ("%s:", *arg2 ? arg2 : arg3);
                  in_fixed_width_font++;
                  execute_string (" %s", arg1);
                  add_xref_punctuation ();
                  in_fixed_width_font--;
                }
            }
          else
            {
              if (html)
                {
                  add_html_elt ("<a href=\"");
                  in_fixed_width_font++;
                  tem = expansion (arg1, 0);
                  in_fixed_width_font--;
                  add_anchor_name (tem, 1);
                  free (tem);
                  add_word ("\">");
                  if (*arg2)
                    execute_string ("%s", arg2);
                  else
                    {
                      char *fref = get_float_ref (arg1);
                      execute_string ("%s", fref ? fref : arg1);
                      free (fref);
                    }
                  add_word ("</a>");
                }
              else
                {
                  if (*arg2)
                    {
                      execute_string ("%s:", arg2);
                      in_fixed_width_font++;
                      execute_string (" %s", arg1);
                      add_xref_punctuation ();
                      in_fixed_width_font--;
                    }
                  else
                    {
                      char *fref = get_float_ref (arg1);
                      if (fref)
                        { /* Reference is being made to a float.  */
                          execute_string ("%s:", fref);
                          in_fixed_width_font++;
                          execute_string (" %s", arg1);
                          add_xref_punctuation ();
                          in_fixed_width_font--;
                        }
                      else
                        {
                          in_fixed_width_font++;
                          execute_string ("%s::", arg1);
                          in_fixed_width_font--;
                        }
                    }
                }
            }
        }
      /* Free all of the arguments found. */
      if (arg1) free (arg1);
      if (arg2) free (arg2);
      if (arg3) free (arg3);
      if (arg4) free (arg4);
      if (arg5) free (arg5);
    }
  else
    { /* Check that the next non-whitespace character is valid to follow
         an xref (so Info readers can find the node names).
         `input_text_offset' is pointing at the "}" which ended the xref
         command.  This is not used for @pxref or @ref, since we insert
         the necessary punctuation above, if needed.  */
      int temp = next_nonwhitespace_character ();

      if (temp == -1)
        warning (_("End of file reached while looking for `.' or `,'"));
      else if (temp != '.' && temp != ',')
        warning (_("`.' or `,' must follow @%s, not `%c'"), command, temp);
    }
}
Пример #18
0
tag_parse_status_t
parse_tag_line (void *ctx, char *line,
		tag_op_flag_t flags,
		char **query_string,
		tag_op_list_t *tag_ops)
{
    char *tok = line;
    size_t tok_len = 0;
    char *line_for_error;
    tag_parse_status_t ret = TAG_PARSE_SUCCESS;

    chomp_newline (line);

    line_for_error = talloc_strdup (ctx, line);
    if (line_for_error == NULL) {
	fprintf (stderr, "Error: out of memory\n");
	return TAG_PARSE_OUT_OF_MEMORY;
    }

    /* remove leading space */
    while (*tok == ' ' || *tok == '\t')
	tok++;

    /* Skip empty and comment lines. */
    if (*tok == '\0' || *tok == '#') {
	ret = TAG_PARSE_SKIPPED;
	goto DONE;
    }

    tag_op_list_reset (tag_ops);

    /* Parse tags. */
    while ((tok = strtok_len (tok + tok_len, " ", &tok_len)) != NULL) {
	notmuch_bool_t remove;
	char *tag;

	/* Optional explicit end of tags marker. */
	if (tok_len == 2 && strncmp (tok, "--", tok_len) == 0) {
	    tok = strtok_len (tok + tok_len, " ", &tok_len);
	    if (tok == NULL) {
		ret = line_error (TAG_PARSE_INVALID, line_for_error,
				  "no query string after --");
		goto DONE;
	    }
	    break;
	}

	/* Implicit end of tags. */
	if (*tok != '-' && *tok != '+')
	    break;

	/* If tag is terminated by NUL, there's no query string. */
	if (*(tok + tok_len) == '\0') {
	    ret = line_error (TAG_PARSE_INVALID, line_for_error,
			      "no query string");
	    goto DONE;
	}

	/* Terminate, and start next token after terminator. */
	*(tok + tok_len++) = '\0';

	remove = (*tok == '-');
	tag = tok + 1;

	/* Maybe refuse illegal tags. */
	if (! (flags & TAG_FLAG_BE_GENEROUS)) {
	    const char *msg = illegal_tag (tag, remove);
	    if (msg) {
		ret = line_error (TAG_PARSE_INVALID, line_for_error, msg);
		goto DONE;
	    }
	}

	/* Decode tag. */
	if (hex_decode_inplace (tag) != HEX_SUCCESS) {
	    ret = line_error (TAG_PARSE_INVALID, line_for_error,
			      "hex decoding of tag %s failed", tag);
	    goto DONE;
	}

	if (tag_op_list_append (tag_ops, tag, remove)) {
	    ret = line_error (TAG_PARSE_OUT_OF_MEMORY, line_for_error,
			      "aborting");
	    goto DONE;
	}
    }

    if (tok == NULL) {
	/* use a different error message for testing */
	ret = line_error (TAG_PARSE_INVALID, line_for_error,
			  "missing query string");
	goto DONE;
    }

    /* tok now points to the query string */
    *query_string = tok;

  DONE:
    talloc_free (line_for_error);
    return ret;
}
Пример #19
0
/* Treat this just like @unnumbered.  The only difference is
   in node defaulting. */
void
cm_top (void)
{
  /* It is an error to have more than one @top. */
  if (top_node_seen && strcmp (current_node, "Top") != 0)
    {
      TAG_ENTRY *tag = tag_table;

      line_error (_("Node with %ctop as a section already exists"),
                  COMMAND_PREFIX);

      while (tag)
        {
          if (tag->flags & TAG_FLAG_IS_TOP)
            {
              file_line_error (tag->filename, tag->line_no,
                               _("Here is the %ctop node"), COMMAND_PREFIX);
              return;
            }
          tag = tag->next_ent;
        }
    }
  else
    {
      top_node_seen = 1;

      /* It is an error to use @top before using @node. */
      if (!tag_table)
        {
          char *top_name;

          get_rest_of_line (0, &top_name);
          line_error (_("%ctop used before %cnode, defaulting to %s"),
                      COMMAND_PREFIX, COMMAND_PREFIX, top_name);
          execute_string ("@node Top, , (dir), (dir)\n@top %s\n", top_name);
          free (top_name);
          return;
        }

      cm_unnumbered ();

      /* The most recently defined node is the top node. */
      tag_table->flags |= TAG_FLAG_IS_TOP;

      /* Now set the logical hierarchical level of the Top node. */
      {
        int orig_offset = input_text_offset;

        input_text_offset = search_forward (node_search_string, orig_offset);

        if (input_text_offset > 0)
          {
            int this_section;

            /* We have encountered a non-top node, so mark that one exists. */
            non_top_node_seen = 1;

            /* Move to the end of this line, and find out what the
               sectioning command is here. */
            while (input_text[input_text_offset] != '\n')
              input_text_offset++;

            if (input_text_offset < input_text_length)
              input_text_offset++;

            this_section = what_section (input_text + input_text_offset,
                                         NULL);

            /* If we found a sectioning command, then give the top section
               a level of this section - 1. */
            if (this_section != -1)
              set_top_section_level (this_section - 1);
          }
        input_text_offset = orig_offset;
      }
    }
}