/* 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; }
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; }
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++; } }
/* 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; }
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; }
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; }
/* 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; }
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); }
/* 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; }
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); }
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++; } }
/* 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); } }
/* 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); }
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); }
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); } }
/* 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); } }
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; }
/* 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; } } }