{"thread":{"id":"11574","subject":"git-write-error with cherry-pick -n usages","startedAt":"2008-01-11T05:48:11Z","lastAt":"2008-02-03T09:11:03Z","messageCount":3,"participants":["Björn Steinbrink","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"64980","messageId":"20080111054811.GA7476@atjola.homenet","threadId":"11574","inReplyTo":null,"subject":"git-write-error with cherry-pick -n usages","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2008-01-11T05:48:11Z","receivedAt":"2008-01-11T05:48:11Z","isPatch":false,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"Hi,\n\nwhen you cherry-pick -n a commit that has changes to a file missing in\nthe current tree, that file will be added as \"Unmerged\". A subsequent\ncherry-pick that tries to pick a commit that has changes to that file\nwill then fail with:\n\nfatal: git-write-tree: error building trees\n\nI've attached a small shell script to easily reproduce that.\n\ngit version 1.5.4.rc2.84.gf85fd\n\nThat specific use of cherry-pick might be an user error, but, if\npossible, git should give a less cryptic error message.\n\nBjörn\n"},{"id":"64983","messageId":"7vr6go501s.fsf@gitster.siamese.dyndns.org","threadId":"11574","inReplyTo":"20080111054811.GA7476@atjola.homenet","subject":"Re: git-write-error with cherry-pick -n usages","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-01-11T06:49:35Z","receivedAt":"2008-01-11T06:49:35Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n\n> when you cherry-pick -n a commit that has changes to a file missing in\n> the current tree, that file will be added as \"Unmerged\". A subsequent\n> cherry-pick that tries to pick a commit that has changes to that file\n> will then fail with:\n>\n> fatal: git-write-tree: error building trees\n\nYeah, this was because the original \"rewrite in C\" did somewhat\na sloppy job while stealing code from git-write-tree.\n\nThe caller pretends as if the write_tree() function would return\nan error code and being able to issue a sensible error message\nitself, but write_tree() function just calls die() and never\nreturns an error.  Worse yet, the function claims that it was\nrunning git-write-tree (which is no longer true after\ncherry-pick stole it).\n\nI think you would need to do something like this patch.  I will\nnot apply it during the -rc period, but testing and resending\nwith \"Tested-by:\" would be helpful after post 1.5.4 cycle opens.\n\n---\n builtin-revert.c     |    5 ++-\n builtin-write-tree.c |   74 +++++++++++---------------------------------------\n builtin.h            |    1 -\n cache-tree.c         |   59 +++++++++++++++++++++++++++++++++++++++\n cache-tree.h         |    5 +++\n 5 files changed, 83 insertions(+), 61 deletions(-)\n\ndiff --git a/builtin-revert.c b/builtin-revert.c\nindex 4bf8eb2..d71f414 100644\n--- a/builtin-revert.c\n+++ b/builtin-revert.c\n@@ -8,6 +8,7 @@\n #include \"exec_cmd.h\"\n #include \"utf8.h\"\n #include \"parse-options.h\"\n+#include \"cache-tree.h\"\n \n /*\n  * This implements the builtins revert and cherry-pick.\n@@ -270,7 +271,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \t\t * that represents the \"current\" state for merge-recursive\n \t\t * to work on.\n \t\t */\n-\t\tif (write_tree(head, 0, NULL))\n+\t\tif (write_cache_as_tree(head, 0, NULL))\n \t\t\tdie (\"Your index file is unmerged.\");\n \t} else {\n \t\tstruct wt_status s;\n@@ -357,7 +358,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \tif (merge_recursive(sha1_to_hex(base->object.sha1),\n \t\t\t\tsha1_to_hex(head), \"HEAD\",\n \t\t\t\tsha1_to_hex(next->object.sha1), oneline) ||\n-\t\t\twrite_tree(head, 0, NULL)) {\n+\t\t\twrite_cache_as_tree(head, 0, NULL)) {\n \t\tadd_to_msg(\"\\nConflicts:\\n\\n\");\n \t\tread_cache();\n \t\tfor (i = 0; i < active_nr;) {\ndiff --git a/builtin-write-tree.c b/builtin-write-tree.c\nindex b89d02e..e838d01 100644\n--- a/builtin-write-tree.c\n+++ b/builtin-write-tree.c\n@@ -11,66 +11,12 @@\n static const char write_tree_usage[] =\n \"git-write-tree [--missing-ok] [--prefix=<prefix>/]\";\n \n-int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)\n-{\n-\tint entries, was_valid, newfd;\n-\n-\t/* We can't free this memory, it becomes part of a linked list parsed atexit() */\n-\tstruct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));\n-\n-\tnewfd = hold_locked_index(lock_file, 1);\n-\n-\tentries = read_cache();\n-\tif (entries < 0)\n-\t\tdie(\"git-write-tree: error reading cache\");\n-\n-\tif (!active_cache_tree)\n-\t\tactive_cache_tree = cache_tree();\n-\n-\twas_valid = cache_tree_fully_valid(active_cache_tree);\n-\n-\tif (!was_valid) {\n-\t\tif (cache_tree_update(active_cache_tree,\n-\t\t\t\t      active_cache, active_nr,\n-\t\t\t\t      missing_ok, 0) < 0)\n-\t\t\tdie(\"git-write-tree: error building trees\");\n-\t\tif (0 <= newfd) {\n-\t\t\tif (!write_cache(newfd, active_cache, active_nr)\n-\t\t\t\t\t&& !close(newfd)) {\n-\t\t\t\tcommit_lock_file(lock_file);\n-\t\t\t\tnewfd = -1;\n-\t\t\t}\n-\t\t}\n-\t\t/* Not being able to write is fine -- we are only interested\n-\t\t * in updating the cache-tree part, and if the next caller\n-\t\t * ends up using the old index with unupdated cache-tree part\n-\t\t * it misses the work we did here, but that is just a\n-\t\t * performance penalty and not a big deal.\n-\t\t */\n-\t}\n-\n-\tif (prefix) {\n-\t\tstruct cache_tree *subtree =\n-\t\t\tcache_tree_find(active_cache_tree, prefix);\n-\t\tif (!subtree)\n-\t\t\tdie(\"git-write-tree: prefix %s not found\", prefix);\n-\t\thashcpy(sha1, subtree->sha1);\n-\t}\n-\telse\n-\t\thashcpy(sha1, active_cache_tree->sha1);\n-\n-\tif (0 <= newfd)\n-\t\tclose(newfd);\n-\trollback_lock_file(lock_file);\n-\n-\treturn 0;\n-}\n-\n int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)\n {\n \tint missing_ok = 0, ret;\n \tconst char *prefix = NULL;\n \tunsigned char sha1[20];\n+\tconst char *me = \"git-write-tree\";\n \n \tgit_config(git_default_config);\n \twhile (1 < argc) {\n@@ -87,8 +33,20 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)\n \tif (argc > 2)\n \t\tdie(\"too many options\");\n \n-\tret = write_tree(sha1, missing_ok, prefix);\n-\tprintf(\"%s\\n\", sha1_to_hex(sha1));\n-\n+\tret = write_cache_as_tree(sha1, missing_ok, prefix);\n+\tswitch (ret) {\n+\tcase 0:\n+\t\tprintf(\"%s\\n\", sha1_to_hex(sha1));\n+\t\tbreak;\n+\tcase WRITE_TREE_UNREADABLE_INDEX:\n+\t\tdie(\"%s: error reading the index\", me);\n+\t\tbreak;\n+\tcase WRITE_TREE_UNMERGED_INDEX:\n+\t\tdie(\"%s: error building trees; the index is unmerged?\", me);\n+\t\tbreak;\n+\tcase WRITE_TREE_PREFIX_ERROR:\n+\t\tdie(\"%s: prefix %s not found\", me, prefix);\n+\t\tbreak;\n+\t}\n \treturn ret;\n }\ndiff --git a/builtin.h b/builtin.h\nindex cb675c4..3d1628c 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -8,7 +8,6 @@ extern const char git_usage_string[];\n \n extern void list_common_cmds_help(void);\n extern void help_unknown_cmd(const char *cmd);\n-extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);\n extern void prune_packed_objects(int);\n \n extern int cmd_add(int argc, const char **argv, const char *prefix);\ndiff --git a/cache-tree.c b/cache-tree.c\nindex 50b3526..69d0b46 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -529,3 +529,62 @@ struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path)\n \t}\n \treturn it;\n }\n+\n+int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix)\n+{\n+\tint entries, was_valid, newfd;\n+\n+\t/*\n+\t * We can't free this memory, it becomes part of a linked list\n+\t * parsed atexit()\n+\t */\n+\tstruct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));\n+\n+\tnewfd = hold_locked_index(lock_file, 1);\n+\n+\tentries = read_cache();\n+\tif (entries < 0)\n+\t\treturn WRITE_TREE_UNREADABLE_INDEX;\n+\n+\tif (!active_cache_tree)\n+\t\tactive_cache_tree = cache_tree();\n+\n+\twas_valid = cache_tree_fully_valid(active_cache_tree);\n+\n+\tif (!was_valid) {\n+\t\tif (cache_tree_update(active_cache_tree,\n+\t\t\t\t      active_cache, active_nr,\n+\t\t\t\t      missing_ok, 0) < 0)\n+\t\t\treturn WRITE_TREE_UNMERGED_INDEX;\n+\t\tif (0 <= newfd) {\n+\t\t\tif (!write_cache(newfd, active_cache, active_nr)\n+\t\t\t\t\t&& !close(newfd)) {\n+\t\t\t\tcommit_lock_file(lock_file);\n+\t\t\t\tnewfd = -1;\n+\t\t\t}\n+\t\t}\n+\t\t/* Not being able to write is fine -- we are only interested\n+\t\t * in updating the cache-tree part, and if the next caller\n+\t\t * ends up using the old index with unupdated cache-tree part\n+\t\t * it misses the work we did here, but that is just a\n+\t\t * performance penalty and not a big deal.\n+\t\t */\n+\t}\n+\n+\tif (prefix) {\n+\t\tstruct cache_tree *subtree =\n+\t\t\tcache_tree_find(active_cache_tree, prefix);\n+\t\tif (!subtree)\n+\t\t\treturn WRITE_TREE_PREFIX_ERROR;\n+\t\thashcpy(sha1, subtree->sha1);\n+\t}\n+\telse\n+\t\thashcpy(sha1, active_cache_tree->sha1);\n+\n+\tif (0 <= newfd)\n+\t\tclose(newfd);\n+\trollback_lock_file(lock_file);\n+\n+\treturn 0;\n+}\n+\ndiff --git a/cache-tree.h b/cache-tree.h\nindex 8243228..44aad42 100644\n--- a/cache-tree.h\n+++ b/cache-tree.h\n@@ -30,4 +30,9 @@ int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int, int)\n \n struct cache_tree *cache_tree_find(struct cache_tree *, const char *);\n \n+#define WRITE_TREE_UNREADABLE_INDEX (-1)\n+#define WRITE_TREE_UNMERGED_INDEX (-2)\n+#define WRITE_TREE_PREFIX_ERROR (-3)\n+\n+int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix);\n #endif\n"},{"id":"67197","messageId":"20080203091103.GA4415@atjola.homenet","threadId":"11574","inReplyTo":"7vr6go501s.fsf@gitster.siamese.dyndns.org","subject":"Re: git-write-error with cherry-pick -n usages","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2008-02-03T09:11:03Z","receivedAt":"2008-02-03T09:11:03Z","isPatch":false,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2008.01.10 22:49:35 -0800, Junio C Hamano wrote:\n> Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n> \n> > when you cherry-pick -n a commit that has changes to a file missing in\n> > the current tree, that file will be added as \"Unmerged\". A subsequent\n> > cherry-pick that tries to pick a commit that has changes to that file\n> > will then fail with:\n> >\n> > fatal: git-write-tree: error building trees\n> \n> Yeah, this was because the original \"rewrite in C\" did somewhat\n> a sloppy job while stealing code from git-write-tree.\n> \n> The caller pretends as if the write_tree() function would return\n> an error code and being able to issue a sensible error message\n> itself, but write_tree() function just calls die() and never\n> returns an error.  Worse yet, the function claims that it was\n> running git-write-tree (which is no longer true after\n> cherry-pick stole it).\n> \n> I think you would need to do something like this patch.  I will\n> not apply it during the -rc period, but testing and resending\n> with \"Tested-by:\" would be helpful after post 1.5.4 cycle opens.\n\nSorry for the delay, that mail got lost somewhere in the noise of my\ninbox and real life. Successfully tested the patch to generate an useful\nerror message, as well as surviving the test suite and working correctly\non a random set of cherry-picks in some of my repos.\n\nThanks!\n\nTested-by: Björn Steinbrink <B.Steinbrink@gmx.de>\n\n> \n> ---\n>  builtin-revert.c     |    5 ++-\n>  builtin-write-tree.c |   74 +++++++++++---------------------------------------\n>  builtin.h            |    1 -\n>  cache-tree.c         |   59 +++++++++++++++++++++++++++++++++++++++\n>  cache-tree.h         |    5 +++\n>  5 files changed, 83 insertions(+), 61 deletions(-)\n> \n> diff --git a/builtin-revert.c b/builtin-revert.c\n> index 4bf8eb2..d71f414 100644\n> --- a/builtin-revert.c\n> +++ b/builtin-revert.c\n> @@ -8,6 +8,7 @@\n>  #include \"exec_cmd.h\"\n>  #include \"utf8.h\"\n>  #include \"parse-options.h\"\n> +#include \"cache-tree.h\"\n>  \n>  /*\n>   * This implements the builtins revert and cherry-pick.\n> @@ -270,7 +271,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n>  \t\t * that represents the \"current\" state for merge-recursive\n>  \t\t * to work on.\n>  \t\t */\n> -\t\tif (write_tree(head, 0, NULL))\n> +\t\tif (write_cache_as_tree(head, 0, NULL))\n>  \t\t\tdie (\"Your index file is unmerged.\");\n>  \t} else {\n>  \t\tstruct wt_status s;\n> @@ -357,7 +358,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n>  \tif (merge_recursive(sha1_to_hex(base->object.sha1),\n>  \t\t\t\tsha1_to_hex(head), \"HEAD\",\n>  \t\t\t\tsha1_to_hex(next->object.sha1), oneline) ||\n> -\t\t\twrite_tree(head, 0, NULL)) {\n> +\t\t\twrite_cache_as_tree(head, 0, NULL)) {\n>  \t\tadd_to_msg(\"\\nConflicts:\\n\\n\");\n>  \t\tread_cache();\n>  \t\tfor (i = 0; i < active_nr;) {\n> diff --git a/builtin-write-tree.c b/builtin-write-tree.c\n> index b89d02e..e838d01 100644\n> --- a/builtin-write-tree.c\n> +++ b/builtin-write-tree.c\n> @@ -11,66 +11,12 @@\n>  static const char write_tree_usage[] =\n>  \"git-write-tree [--missing-ok] [--prefix=<prefix>/]\";\n>  \n> -int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)\n> -{\n> -\tint entries, was_valid, newfd;\n> -\n> -\t/* We can't free this memory, it becomes part of a linked list parsed atexit() */\n> -\tstruct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));\n> -\n> -\tnewfd = hold_locked_index(lock_file, 1);\n> -\n> -\tentries = read_cache();\n> -\tif (entries < 0)\n> -\t\tdie(\"git-write-tree: error reading cache\");\n> -\n> -\tif (!active_cache_tree)\n> -\t\tactive_cache_tree = cache_tree();\n> -\n> -\twas_valid = cache_tree_fully_valid(active_cache_tree);\n> -\n> -\tif (!was_valid) {\n> -\t\tif (cache_tree_update(active_cache_tree,\n> -\t\t\t\t      active_cache, active_nr,\n> -\t\t\t\t      missing_ok, 0) < 0)\n> -\t\t\tdie(\"git-write-tree: error building trees\");\n> -\t\tif (0 <= newfd) {\n> -\t\t\tif (!write_cache(newfd, active_cache, active_nr)\n> -\t\t\t\t\t&& !close(newfd)) {\n> -\t\t\t\tcommit_lock_file(lock_file);\n> -\t\t\t\tnewfd = -1;\n> -\t\t\t}\n> -\t\t}\n> -\t\t/* Not being able to write is fine -- we are only interested\n> -\t\t * in updating the cache-tree part, and if the next caller\n> -\t\t * ends up using the old index with unupdated cache-tree part\n> -\t\t * it misses the work we did here, but that is just a\n> -\t\t * performance penalty and not a big deal.\n> -\t\t */\n> -\t}\n> -\n> -\tif (prefix) {\n> -\t\tstruct cache_tree *subtree =\n> -\t\t\tcache_tree_find(active_cache_tree, prefix);\n> -\t\tif (!subtree)\n> -\t\t\tdie(\"git-write-tree: prefix %s not found\", prefix);\n> -\t\thashcpy(sha1, subtree->sha1);\n> -\t}\n> -\telse\n> -\t\thashcpy(sha1, active_cache_tree->sha1);\n> -\n> -\tif (0 <= newfd)\n> -\t\tclose(newfd);\n> -\trollback_lock_file(lock_file);\n> -\n> -\treturn 0;\n> -}\n> -\n>  int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)\n>  {\n>  \tint missing_ok = 0, ret;\n>  \tconst char *prefix = NULL;\n>  \tunsigned char sha1[20];\n> +\tconst char *me = \"git-write-tree\";\n>  \n>  \tgit_config(git_default_config);\n>  \twhile (1 < argc) {\n> @@ -87,8 +33,20 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)\n>  \tif (argc > 2)\n>  \t\tdie(\"too many options\");\n>  \n> -\tret = write_tree(sha1, missing_ok, prefix);\n> -\tprintf(\"%s\\n\", sha1_to_hex(sha1));\n> -\n> +\tret = write_cache_as_tree(sha1, missing_ok, prefix);\n> +\tswitch (ret) {\n> +\tcase 0:\n> +\t\tprintf(\"%s\\n\", sha1_to_hex(sha1));\n> +\t\tbreak;\n> +\tcase WRITE_TREE_UNREADABLE_INDEX:\n> +\t\tdie(\"%s: error reading the index\", me);\n> +\t\tbreak;\n> +\tcase WRITE_TREE_UNMERGED_INDEX:\n> +\t\tdie(\"%s: error building trees; the index is unmerged?\", me);\n> +\t\tbreak;\n> +\tcase WRITE_TREE_PREFIX_ERROR:\n> +\t\tdie(\"%s: prefix %s not found\", me, prefix);\n> +\t\tbreak;\n> +\t}\n>  \treturn ret;\n>  }\n> diff --git a/builtin.h b/builtin.h\n> index cb675c4..3d1628c 100644\n> --- a/builtin.h\n> +++ b/builtin.h\n> @@ -8,7 +8,6 @@ extern const char git_usage_string[];\n>  \n>  extern void list_common_cmds_help(void);\n>  extern void help_unknown_cmd(const char *cmd);\n> -extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);\n>  extern void prune_packed_objects(int);\n>  \n>  extern int cmd_add(int argc, const char **argv, const char *prefix);\n> diff --git a/cache-tree.c b/cache-tree.c\n> index 50b3526..69d0b46 100644\n> --- a/cache-tree.c\n> +++ b/cache-tree.c\n> @@ -529,3 +529,62 @@ struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path)\n>  \t}\n>  \treturn it;\n>  }\n> +\n> +int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix)\n> +{\n> +\tint entries, was_valid, newfd;\n> +\n> +\t/*\n> +\t * We can't free this memory, it becomes part of a linked list\n> +\t * parsed atexit()\n> +\t */\n> +\tstruct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));\n> +\n> +\tnewfd = hold_locked_index(lock_file, 1);\n> +\n> +\tentries = read_cache();\n> +\tif (entries < 0)\n> +\t\treturn WRITE_TREE_UNREADABLE_INDEX;\n> +\n> +\tif (!active_cache_tree)\n> +\t\tactive_cache_tree = cache_tree();\n> +\n> +\twas_valid = cache_tree_fully_valid(active_cache_tree);\n> +\n> +\tif (!was_valid) {\n> +\t\tif (cache_tree_update(active_cache_tree,\n> +\t\t\t\t      active_cache, active_nr,\n> +\t\t\t\t      missing_ok, 0) < 0)\n> +\t\t\treturn WRITE_TREE_UNMERGED_INDEX;\n> +\t\tif (0 <= newfd) {\n> +\t\t\tif (!write_cache(newfd, active_cache, active_nr)\n> +\t\t\t\t\t&& !close(newfd)) {\n> +\t\t\t\tcommit_lock_file(lock_file);\n> +\t\t\t\tnewfd = -1;\n> +\t\t\t}\n> +\t\t}\n> +\t\t/* Not being able to write is fine -- we are only interested\n> +\t\t * in updating the cache-tree part, and if the next caller\n> +\t\t * ends up using the old index with unupdated cache-tree part\n> +\t\t * it misses the work we did here, but that is just a\n> +\t\t * performance penalty and not a big deal.\n> +\t\t */\n> +\t}\n> +\n> +\tif (prefix) {\n> +\t\tstruct cache_tree *subtree =\n> +\t\t\tcache_tree_find(active_cache_tree, prefix);\n> +\t\tif (!subtree)\n> +\t\t\treturn WRITE_TREE_PREFIX_ERROR;\n> +\t\thashcpy(sha1, subtree->sha1);\n> +\t}\n> +\telse\n> +\t\thashcpy(sha1, active_cache_tree->sha1);\n> +\n> +\tif (0 <= newfd)\n> +\t\tclose(newfd);\n> +\trollback_lock_file(lock_file);\n> +\n> +\treturn 0;\n> +}\n> +\n> diff --git a/cache-tree.h b/cache-tree.h\n> index 8243228..44aad42 100644\n> --- a/cache-tree.h\n> +++ b/cache-tree.h\n> @@ -30,4 +30,9 @@ int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int, int)\n>  \n>  struct cache_tree *cache_tree_find(struct cache_tree *, const char *);\n>  \n> +#define WRITE_TREE_UNREADABLE_INDEX (-1)\n> +#define WRITE_TREE_UNMERGED_INDEX (-2)\n> +#define WRITE_TREE_PREFIX_ERROR (-3)\n> +\n> +int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix);\n>  #endif\n"}]}