131
/* Prepend and append new paths to include_files_path. */
133
prepend_to_include_path (char *path)
135
if (!include_files_path)
137
include_files_path = xstrdup (path);
138
include_files_path = xrealloc (include_files_path,
139
strlen (include_files_path) + 3); /* 3 for ":.\0" */
140
strcat (strcat (include_files_path, PATH_SEP), ".");
144
char *tmp = xstrdup (include_files_path);
145
include_files_path = xrealloc (include_files_path,
146
strlen (include_files_path) + strlen (path) + 2); /* 2 for ":\0" */
147
strcpy (include_files_path, path);
148
strcat (include_files_path, PATH_SEP);
149
strcat (include_files_path, tmp);
155
append_to_include_path (char *path)
157
if (!include_files_path)
158
include_files_path = xstrdup (".");
160
include_files_path = (char *) xrealloc (include_files_path,
161
2 + strlen (include_files_path) + strlen (path));
162
strcat (include_files_path, PATH_SEP);
163
strcat (include_files_path, path);
166
/* Remove the first path from the include_files_path. */
168
pop_path_from_include_path (void)
173
if (include_files_path)
174
for (i = 0; i < strlen (include_files_path)
175
&& include_files_path[i] != ':'; i++);
177
/* Advance include_files_path to the next char from ':' */
178
tmp = (char *) xmalloc (strlen (include_files_path) - i);
179
strcpy (tmp, (char *) include_files_path + i + 1);
181
free (include_files_path);
182
include_files_path = tmp;
132
185
/* Find and load the file named FILENAME. Return a pointer to
133
the loaded file, or NULL if it can't be loaded. */
186
the loaded file, or NULL if it can't be loaded. If USE_PATH is zero,
187
just look for the given file (this is used in handle_delayed_writes),
188
else search along include_files_path. */
135
find_and_load (filename)
191
find_and_load (char *filename, int use_path)
138
193
struct stat fileinfo;
357
/* Return the expansion of FILENAME. */
359
expand_filename (filename, input_name)
360
char *filename, *input_name;
363
char *full_pathname ();
367
filename = full_pathname (filename);
368
if (IS_ABSOLUTE (filename)
369
|| (*filename == '.' &&
370
(IS_SLASH (filename[1]) ||
371
(filename[1] == '.' && IS_SLASH (filename[2])))))
376
filename = filename_non_directory (input_name);
381
filename = xstrdup ("noname.texi");
384
for (i = strlen (filename) - 1; i; i--)
385
if (filename[i] == '.')
389
i = strlen (filename);
391
if (i + 6 > (strlen (filename)))
392
filename = xrealloc (filename, i + 6);
393
strcpy (filename + i, html ? ".html" : ".info");
397
if (IS_ABSOLUTE (input_name))
399
/* Make it so that relative names work. */
402
i = strlen (input_name) - 1;
404
result = xmalloc (1 + strlen (input_name) + strlen (filename));
405
strcpy (result, input_name);
407
while (!IS_SLASH (result[i]) && i)
409
if (IS_SLASH (result[i]))
412
strcpy (&result[i], filename);
419
407
/* Return the full path to FILENAME. */
421
full_pathname (filename)
409
full_pathname (char *filename)
424
411
int initial_character;
513
output_name_from_input_name (name)
499
/* Return the expansion of FILENAME. */
501
expand_filename (char *filename, char *input_name)
507
filename = full_pathname (filename);
508
if (IS_ABSOLUTE (filename)
509
|| (*filename == '.' &&
510
(IS_SLASH (filename[1]) ||
511
(filename[1] == '.' && IS_SLASH (filename[2])))))
516
filename = filename_non_directory (input_name);
521
filename = xstrdup ("noname.texi");
524
for (i = strlen (filename) - 1; i; i--)
525
if (filename[i] == '.')
529
i = strlen (filename);
531
if (i + 6 > (strlen (filename)))
532
filename = xrealloc (filename, i + 6);
533
strcpy (filename + i, html ? ".html" : ".info");
537
if (IS_ABSOLUTE (input_name))
539
/* Make it so that relative names work. */
542
i = strlen (input_name) - 1;
544
result = xmalloc (1 + strlen (input_name) + strlen (filename));
545
strcpy (result, input_name);
547
while (!IS_SLASH (result[i]) && i)
549
if (IS_SLASH (result[i]))
552
strcpy (&result[i], filename);
560
output_name_from_input_name (char *name)
516
562
return expand_filename (NULL, name);
623
/* Delayed writing functions. A few of the commands
624
needs to be handled at the end, namely @contents,
625
@shortcontents, @printindex and @listoffloats.
626
These functions take care of that. */
627
static DELAYED_WRITE *delayed_writes = NULL;
628
int handling_delayed_writes = 0;
631
register_delayed_write (char *delayed_command)
635
if (!current_output_filename || !*current_output_filename)
637
/* Cannot register if we don't know what the output file is. */
638
warning (_("`%s' omitted before output filename"), delayed_command);
642
if (STREQ (current_output_filename, "-"))
644
/* Do not register a new write if the output file is not seekable.
645
Let the user know about it first, though. */
646
warning (_("`%s' omitted since writing to stdout"), delayed_command);
650
/* Don't complain if the user is writing /dev/null, since surely they
651
don't care, but don't register the delayed write, either. */
652
if (FILENAME_CMP (current_output_filename, NULL_DEVICE) == 0
653
|| FILENAME_CMP (current_output_filename, ALSO_NULL_DEVICE) == 0)
656
/* We need the HTML header in the output,
657
to get a proper output_position. */
658
if (!executing_string && html)
660
/* Get output_position updated. */
663
new = xmalloc (sizeof (DELAYED_WRITE));
664
new->command = xstrdup (delayed_command);
665
new->filename = xstrdup (current_output_filename);
666
new->input_filename = xstrdup (input_filename);
667
new->position = output_position;
668
new->calling_line = line_number;
669
new->node = current_node ? xstrdup (current_node): "";
671
new->node_order = node_order;
672
new->index_order = index_counter;
674
new->next = delayed_writes;
675
delayed_writes = new;
679
handle_delayed_writes (void)
681
DELAYED_WRITE *temp = (DELAYED_WRITE *) reverse_list
682
((GENERIC_LIST *) delayed_writes);
683
int position_shift_amount, line_number_shift_amount;
686
handling_delayed_writes = 1;
690
delayed_buf = find_and_load (temp->filename, 0);
692
if (output_paragraph_offset > 0)
694
error (_("Output buffer not empty."));
700
fs_error (temp->filename);
704
output_stream = fopen (temp->filename, "w");
707
fs_error (temp->filename);
711
if (fwrite (delayed_buf, 1, temp->position, output_stream) != temp->position)
713
fs_error (temp->filename);
718
int output_position_at_start = output_position;
719
int line_number_at_start = output_line_number;
721
/* In order to make warnings and errors
722
refer to the correct line number. */
723
input_filename = temp->input_filename;
724
line_number = temp->calling_line;
726
execute_string ("%s", temp->command);
729
/* Since the output file is modified, following delayed writes
730
need to be updated by this amount. */
731
position_shift_amount = output_position - output_position_at_start;
732
line_number_shift_amount = output_line_number - line_number_at_start;
735
if (fwrite (delayed_buf + temp->position, 1,
736
input_text_length - temp->position, output_stream)
737
!= input_text_length - temp->position
738
|| fclose (output_stream) != 0)
739
fs_error (temp->filename);
741
/* Done with the buffer. */
744
/* Update positions in tag table for nodes that are defined after
745
the line this delayed write is registered. */
749
for (node = tag_table; node; node = node->next_ent)
750
if (node->order > temp->node_order)
751
node->position += position_shift_amount;
754
/* Something similar for the line numbers in all of the defined
758
for (i = 0; i < defined_indices; i++)
759
if (name_index_alist[i])
761
char *name = ((INDEX_ALIST *) name_index_alist[i])->name;
763
for (index = index_list (name); index; index = index->next)
764
if ((no_headers || STREQ (index->node, temp->node))
765
&& index->entry_number > temp->index_order)
766
index->output_line += line_number_shift_amount;
770
/* Shift remaining delayed positions
771
by the length of this write. */
773
DELAYED_WRITE *future_write = temp->next;
776
if (STREQ (temp->filename, future_write->filename))
777
future_write->position += position_shift_amount;
778
future_write = future_write->next;