[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
From: |
Patrice Dumas |
Date: |
Sun, 29 Sep 2024 03:01:54 -0400 (EDT) |
branch: master
commit 62df9dda7d34ad5ca286f92c02fedca73b113a51
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Fri Jun 7 11:29:50 2024 +0200
* tp/Texinfo/XS/main/element_types.awk: block_line_arg and line_arg
hold spaces_after_cmd_before_arg and comment_at_end, not the commands.
* tp/Texinfo/XS/main/build_perl_info.c (store_info_element)
(element_to_perl_hash), tp/Texinfo/XS/main/convert_to_texinfo.c
(convert_to_texinfo_internal), tp/Texinfo/XS/main/manipulate_tree.c
(copy_element, copy_associated_info, copy_tree_internal)
(copy_extra_info), tp/Texinfo/XS/main/tree.c (new_element)
(destroy_element), tp/Texinfo/XS/main/tree_types.h
(enum elt_info_type), tp/Texinfo/XS/parsetexi/parser.c
(isolate_last_space),
tp/Texinfo/XS/structuring_transfo/transformations.c (new_node):
initialize, free, copy elt_info list of elements meant to replace
the elements in info. Put comment_at_end in that list instead of
in the info structure and pass it to Perl.
* tp/Texinfo/XS/main/tree_types.h (enum string_info_type, ELEMENT):
prepare string information in element to replace information in info.
---
ChangeLog | 21 +++++++
tp/TODO | 1 +
tp/Texinfo/XS/main/build_perl_info.c | 43 ++++++++++++-
tp/Texinfo/XS/main/convert_to_texinfo.c | 9 ++-
tp/Texinfo/XS/main/element_types.awk | 10 ++-
tp/Texinfo/XS/main/element_types.c | 8 +--
tp/Texinfo/XS/main/manipulate_tree.c | 71 ++++++++++++++++++----
tp/Texinfo/XS/main/tree.c | 14 +++++
tp/Texinfo/XS/main/tree_types.h | 19 ++++++
tp/Texinfo/XS/parsetexi/parser.c | 4 +-
.../XS/structuring_transfo/transformations.c | 3 +-
11 files changed, 177 insertions(+), 26 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a313be4dc4..8b62764249 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2024-06-07 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/XS/main/element_types.awk: block_line_arg and line_arg
+ hold spaces_after_cmd_before_arg and comment_at_end, not the commands.
+
+ * tp/Texinfo/XS/main/build_perl_info.c (store_info_element)
+ (element_to_perl_hash), tp/Texinfo/XS/main/convert_to_texinfo.c
+ (convert_to_texinfo_internal), tp/Texinfo/XS/main/manipulate_tree.c
+ (copy_element, copy_associated_info, copy_tree_internal)
+ (copy_extra_info), tp/Texinfo/XS/main/tree.c (new_element)
+ (destroy_element), tp/Texinfo/XS/main/tree_types.h
+ (enum elt_info_type), tp/Texinfo/XS/parsetexi/parser.c
+ (isolate_last_space),
+ tp/Texinfo/XS/structuring_transfo/transformations.c (new_node):
+ initialize, free, copy elt_info list of elements meant to replace
+ the elements in info. Put comment_at_end in that list instead of
+ in the info structure and pass it to Perl.
+
+ * tp/Texinfo/XS/main/tree_types.h (enum string_info_type, ELEMENT):
+ prepare string information in element to replace information in info.
+
2024-06-05 Patrice Dumas <pertusus@free.fr>
Do not use unnamed union for KEY_PAIR in rebased code
diff --git a/tp/TODO b/tp/TODO
index 239804414f..60e78bfeba 100644
--- a/tp/TODO
+++ b/tp/TODO
@@ -76,6 +76,7 @@ Gavin and Patrice
char *alias_of
char *command_info_string (for arg_line or command_name or @verb delimiter)
ELEMENT *elements[3]
+in block_command line_command
spaces_after_cmd_before_arg (brace commands) or comment_at_end (line/block
commands)
for type brace_arg, line and block commands, BRACE_context commands
spaces_before_argument, spaces_after_argument
diff --git a/tp/Texinfo/XS/main/build_perl_info.c
b/tp/Texinfo/XS/main/build_perl_info.c
index 37ef6beea1..14d84b4800 100644
--- a/tp/Texinfo/XS/main/build_perl_info.c
+++ b/tp/Texinfo/XS/main/build_perl_info.c
@@ -541,6 +541,37 @@ store_source_mark_list (const ELEMENT *e)
}
}
+/* FIXME it is inefficient to store and get every time an element
+ is stored, better use additional_info_hv or a pointer on it as an argument
*/
+void
+store_info_element (ELEMENT *e, ELEMENT *info_element, const char *type_key,
+ const char *key, int avoid_recursion, int *nr_info)
+{
+ HV *additional_info_hv;
+
+ dTHX;
+
+ if (*nr_info == 0)
+ {
+ additional_info_hv = (HV *) newHV ();
+ hv_store (e->hv, type_key, strlen (type_key),
+ newRV_inc ((SV *)additional_info_hv), 0);
+ }
+ else
+ {
+ SV **additional_info_sv = hv_fetch (e->hv, type_key,
+ strlen (type_key), 0);
+ additional_info_hv = (HV *)SvRV (*additional_info_sv);
+ }
+
+ (*nr_info)++;
+ if (!info_element->hv || !avoid_recursion)
+ element_to_perl_hash (info_element, avoid_recursion);
+
+ hv_store (additional_info_hv, key, strlen (key),
+ newRV_inc ((SV *)info_element->hv), 0);
+}
+
static int hashes_ready = 0;
static U32 HSH_parent = 0;
static U32 HSH_type = 0;
@@ -640,7 +671,7 @@ element_to_perl_hash (ELEMENT *e, int avoid_recursion)
hv_store (info_hv, "inserted", strlen ("inserted"),
newSViv (1), 0);
hv_store (e->hv, key, strlen (key),
- newRV_inc ((SV *)info_hv), 0);
+ newRV_inc ((SV *)info_hv), 0);
nr_info++;
}
@@ -651,6 +682,16 @@ element_to_perl_hash (ELEMENT *e, int avoid_recursion)
return;
}
+ if (e->type == ET_block_line_arg || e->type == ET_line_arg)
+ {
+ ELEMENT *f = e->elt_info[eit_comment_at_end];
+ if (f)
+ {
+ store_info_element (e, f, "info", "comment_at_end",
+ avoid_recursion, &nr_info);
+ }
+ }
+
/* non-text elements */
store_additional_info (e, &e->c->info_info, "info", &nr_info,
diff --git a/tp/Texinfo/XS/main/convert_to_texinfo.c
b/tp/Texinfo/XS/main/convert_to_texinfo.c
index 1903502e1a..6d120de0c7 100644
--- a/tp/Texinfo/XS/main/convert_to_texinfo.c
+++ b/tp/Texinfo/XS/main/convert_to_texinfo.c
@@ -172,9 +172,12 @@ convert_to_texinfo_internal (const ELEMENT *e, TEXT
*result)
ADD((char *)elt->text->text);
}
- elt = lookup_info_element (e, "comment_at_end");
- if (elt)
- convert_to_texinfo_internal (elt, result);
+ if (e->type == ET_block_line_arg || e->type == ET_line_arg)
+ {
+ elt = e->elt_info[eit_comment_at_end];
+ if (elt)
+ convert_to_texinfo_internal (elt, result);
+ }
if (e->type == ET_bracketed_arg || e->type == ET_bracketed_linemacro_arg)
ADD("}");
diff --git a/tp/Texinfo/XS/main/element_types.awk
b/tp/Texinfo/XS/main/element_types.awk
index d66455259b..acdb231982 100644
--- a/tp/Texinfo/XS/main/element_types.awk
+++ b/tp/Texinfo/XS/main/element_types.awk
@@ -59,11 +59,15 @@ END {
t = types[line_idx]
flags_str = ""
elt_info_number = 0;
+ # line_command: spaces_before_argument
+ # block_line_arg: spaces_before_argument
if (t == "macro_call" || t == "rmacro_call" \
- || t == "brace_noarg_command" || t == "brace_command") {
+ || t == "brace_noarg_command" || t == "brace_command" \
+ || t == "block_command" || t == "line_command" ) {
elt_info_number = 1;
- } else if (t == "line_command" || t == "block_command" \
- || t == "brace_arg" || t == "bracketed_arg") {
+ # block_line_arg and line_arg: comment_at_end, spaces_after_argument
+ } else if (t == "brace_arg" || t == "bracketed_arg" \
+ || t == "block_line_arg" || t == "line_arg") {
elt_info_number = 2;
} else if (t == "context_brace_command") {
elt_info_number = 3;
diff --git a/tp/Texinfo/XS/main/element_types.c
b/tp/Texinfo/XS/main/element_types.c
index 49721843fa..e0a9b358b1 100644
--- a/tp/Texinfo/XS/main/element_types.c
+++ b/tp/Texinfo/XS/main/element_types.c
@@ -10,8 +10,8 @@ TYPE_DATA type_data[] = {
"brace_noarg_command", 0, 1,
"container_command", 0, 0,
"lineraw_command", 0, 0,
-"line_command", 0, 2,
-"block_command", 0, 2,
+"line_command", 0, 1,
+"block_command", 0, 1,
"brace_command", 0, 1,
"brace_args_command", 0, 0,
"context_brace_command", 0, 3,
@@ -41,8 +41,8 @@ TYPE_DATA type_data[] = {
"brace_container", 0, 0,
"brace_command_context", 0, 0,
"brace_arg", 0, 2,
-"block_line_arg", 0, 0,
-"line_arg", 0, 0,
+"block_line_arg", 0, 2,
+"line_arg", 0, 2,
"following_arg", 0, 0,
"rawline_arg", TF_text, 0,
"menu_entry", 0, 0,
diff --git a/tp/Texinfo/XS/main/manipulate_tree.c
b/tp/Texinfo/XS/main/manipulate_tree.c
index 1820212465..4ba6619ed2 100644
--- a/tp/Texinfo/XS/main/manipulate_tree.c
+++ b/tp/Texinfo/XS/main/manipulate_tree.c
@@ -53,6 +53,24 @@ increase_ref_counter (ELEMENT *element)
(*counter_ptr) ++;
}
+ELEMENT *
+copy_element (ELEMENT *f)
+{
+ KEY_PAIR *k_copy;
+ ELEMENT *e = 0;
+ k_copy = lookup_extra_by_index (f, "_copy", -1);
+ if (k_copy)
+ {
+ e = k_copy->k.element;
+ }
+ else
+ {
+ increase_ref_counter (f);
+ }
+ copy_tree_internal (f, 0);
+ return e;
+}
+
void
copy_associated_info (ASSOCIATED_INFO *info, ASSOCIATED_INFO* new_info)
{
@@ -76,18 +94,15 @@ copy_associated_info (ASSOCIATED_INFO *info,
ASSOCIATED_INFO* new_info)
case extra_element_oot:
if (!strcmp (key, "_copy"))
break;
- k_copy = lookup_extra_by_index (f, "_copy", -1);
- if (k_copy)
- {
- KEY_PAIR *k
- = get_associated_info_key (new_info, key, k_ref->type);
- k->k.element = k_copy->k.element;
- }
- else
- {
- increase_ref_counter (f);
- }
- copy_tree_internal (f, 0);
+ {
+ ELEMENT *copy = copy_element (f);
+ if (copy)
+ {
+ KEY_PAIR *k
+ = get_associated_info_key (new_info, key, k_ref->type);
+ k->k.element = copy;
+ }
+ }
break;
case extra_contents:
case extra_directions:
@@ -192,6 +207,17 @@ copy_tree_internal (ELEMENT* current, ELEMENT *parent)
for (i = 0; i < current->c->contents.number; i++)
add_to_element_contents (new,
copy_tree_internal (current->c->contents.list[i], new));
+
+ if (type_data[current->type].elt_info_number > 0)
+ {
+ for (i = 0; i < type_data[current->type].elt_info_number; i++)
+ if (current->elt_info[i])
+ {
+ ELEMENT *copy = copy_element (current->elt_info[i]);
+ if (copy)
+ new->elt_info[i] = copy;
+ }
+ }
copy_associated_info (¤t->c->info_info, &new->c->info_info);
copy_associated_info (¤t->extra_info, &new->extra_info);
return new;
@@ -378,6 +404,27 @@ copy_extra_info (ELEMENT *current, ELEMENT *new)
for (i = 0; i < current->c->contents.number; i++)
copy_extra_info (current->c->contents.list[i],
new->c->contents.list[i]);
+ if (type_data[current->type].elt_info_number > 0)
+ {
+ int j;
+ for (j = 0; j < type_data[current->type].elt_info_number; j++)
+ {
+ if (current->elt_info[j])
+ {
+ ELEMENT *f = current->elt_info[j];
+ const KEY_PAIR *k_copy;
+
+ if (!new->elt_info[j])
+ {
+ ELEMENT *e = get_copy_ref (f);
+ new->elt_info[j] = e;
+ }
+ k_copy = lookup_extra_by_index (f, "_copy", -1);
+ if (k_copy)
+ copy_extra_info (f, k_copy->k.element);
+ }
+ }
+ }
associate_info_references (¤t->c->info_info, &new->c->info_info);
/* text element have _copy and _counter only in extra, not to be copied
*/
diff --git a/tp/Texinfo/XS/main/tree.c b/tp/Texinfo/XS/main/tree.c
index 7c69617405..6790ba3bbf 100644
--- a/tp/Texinfo/XS/main/tree.c
+++ b/tp/Texinfo/XS/main/tree.c
@@ -89,6 +89,14 @@ new_element (enum element_type type)
e->c = (CONTAINER *) malloc (sizeof (CONTAINER));
memset (e->c, 0, sizeof (CONTAINER));
+ if (type_data[type].elt_info_number > 0)
+ {
+ e->elt_info = (ELEMENT **)
+ malloc (sizeof (ELEMENT *) * type_data[type].elt_info_number);
+ memset (e->elt_info, 0,
+ sizeof (ELEMENT *) * type_data[type].elt_info_number);
+ }
+
return e;
}
@@ -209,11 +217,17 @@ destroy_element (ELEMENT *e)
}
else
{
+ int i;
destroy_associated_info (&e->c->info_info);
/* Note the pointers in these lists are not themselves freed. */
free (e->c->contents.list);
free (e->c->args.list);
+ for (i = 0; i < type_data[e->type].elt_info_number; i++)
+ if (e->elt_info[i])
+ destroy_element_and_children (e->elt_info[i]);
+ free (e->elt_info);
+
free (e->c);
}
diff --git a/tp/Texinfo/XS/main/tree_types.h b/tp/Texinfo/XS/main/tree_types.h
index c36cb70714..0db1ea9253 100644
--- a/tp/Texinfo/XS/main/tree_types.h
+++ b/tp/Texinfo/XS/main/tree_types.h
@@ -217,6 +217,23 @@ typedef struct CONTAINER {
OUTPUT_UNIT *associated_unit;
} CONTAINER;
+/* indices in ELEMENT elt_info */
+enum elt_info_type {
+ eit_spaces_after_cmd_before_arg,
+ eit_comment_at_end = 0,
+ eit_types_spaces_before_argument = 0,
+ eit_spaces_before_argument,
+ eit_types_spaces_after_argument = 1,
+ eit_spaces_after_argument,
+};
+
+/* indices in ELEMENT string_info */
+enum string_info_type {
+ sit_alias_of,
+ sit_arg_line,
+ sit_delimiter = 1,
+};
+
typedef struct ELEMENT {
/* Used when building Perl tree only. This should be HV *hv,
but we don't want to include the Perl headers everywhere; */
@@ -227,6 +244,8 @@ typedef struct ELEMENT {
struct ELEMENT *parent;
/* depends on the element, can be space elements, comments */
struct ELEMENT **elt_info;
+ /* depends on the element */
+ char **string_info;
SOURCE_MARK_LIST source_mark_list;
ASSOCIATED_INFO extra_info;
diff --git a/tp/Texinfo/XS/parsetexi/parser.c b/tp/Texinfo/XS/parsetexi/parser.c
index 3cd5d4d483..88b8b7a75f 100644
--- a/tp/Texinfo/XS/parsetexi/parser.c
+++ b/tp/Texinfo/XS/parsetexi/parser.c
@@ -972,8 +972,8 @@ isolate_last_space (ELEMENT *current)
&& (last_contents_child (current)->cmd == CM_c
|| last_contents_child (current)->cmd == CM_comment))
{
- add_info_element_oot (current, "comment_at_end",
- pop_element_from_contents (current));
+ current->elt_info[eit_comment_at_end]
+ = pop_element_from_contents (current);
}
if (current->c->contents.number == 0)
diff --git a/tp/Texinfo/XS/structuring_transfo/transformations.c
b/tp/Texinfo/XS/structuring_transfo/transformations.c
index dd2f53899d..febec05ec6 100644
--- a/tp/Texinfo/XS/structuring_transfo/transformations.c
+++ b/tp/Texinfo/XS/structuring_transfo/transformations.c
@@ -639,7 +639,8 @@ new_node (ERROR_MESSAGE_LIST *error_messages, ELEMENT
*node_tree,
spaces_after);
if (comment_at_end)
- add_info_element_oot (node_line_arg, "comment_at_end", comment_at_end);
+ node_line_arg->elt_info[eit_comment_at_end] = comment_at_end;
+
insert_slice_into_contents (node_line_arg, 0, node_tree, 0,
node_tree->c->contents.number);