Fix missing output when doing info --output - (Closes: #814743)
upstream svn 7022

2016-02-20  Gavin Smith  <gavinsmith0123@gmail.com>

	* info/info.c (get_initial_file): Handle --file option here 
	instead of in 'main', as well as handling invocation as "info 
	'(FILE)NODE'", and the full path to FILE as the "initial file".  Use 
	"dir" as the last resort of the initial file.  Don't add a node to the 
	list of nodes to load.
	(add_initial_nodes): Add "Top" node to list of nodes to load if no 
	others are given.  Remove error message for initial_file undefined.
	(main): Handle --where option separately for --all given and not given.
	* info/session.c (info_follow_menus): Free initial node if following 
	menus strictly and a menu entry is dangling.
	* info/t/node-no-file.sh: Change expected error message.

	This is so that "info --output -" outputs the dir node, as used to 
	happen.  Vincent Lefevre reported that it doesn't happen for
	Texinfo 6.1.

 2016-02-15  Gavin Smith  <gavinsmith0123@gmail.com>
 
 	* doc/texinfo.tex (\setchapterstyle, \headings, \setchapternewpage)
---
 info/dir.c             |    1 
 info/info.c            |  165 +++++++++++++++++++++++++++----------------------
 info/session.c         |    8 ++
 info/t/node-no-file.sh |    4 -
 4 files changed, 102 insertions(+), 76 deletions(-)

--- texinfo.orig/info/dir.c
+++ texinfo/info/dir.c
@@ -52,6 +52,7 @@
 
   node = xmalloc (sizeof (NODE));
   *node = *dir_node;
+  fprintf(stderr, "%p\n", node);
 
   return node;
 }
--- texinfo.orig/info/info.c
+++ texinfo/info/info.c
@@ -165,7 +165,9 @@
 static void init_messages (void);
 
 
-/* Interpret the first non-option argument, either by looking it up as a dir 
+/* Find the first file to load (and possibly the first node as well).
+   If the --file option is given, use that as the file, otherwise try to
+   interpret the first non-option argument, either by looking it up as a dir 
    entry, looking for a file by that name, or finding a man page by that name.  
    Set INITIAL_FILE to the name of the initial Info file. */
 static void
@@ -173,14 +175,69 @@
 {
   REFERENCE *entry;
 
+  /* User used "--file". */
+  if (user_filename)
+    {
+      if (!IS_ABSOLUTE(user_filename) && HAS_SLASH(user_filename)
+          && !(user_filename[0] == '.' && IS_SLASH(user_filename[1])))
+        {
+          /* Prefix "./" to the filename to prevent a lookup
+             in INFOPATH.  */
+          char *s;
+          asprintf (&s, "%s%s", "./", user_filename);
+          free (user_filename);
+          user_filename = s;
+        }
+      if (IS_ABSOLUTE(user_filename) || HAS_SLASH(user_filename))
+        initial_file = info_add_extension (0, user_filename, 0);
+      else
+        initial_file = info_find_fullpath (user_filename, 0);
+
+      if (!initial_file)
+        {
+          if (!filesys_error_number)
+            filesys_error_number = ENOENT;
+          *error = filesys_error_string (user_filename, filesys_error_number);
+        }
+
+      return;
+    }
+
   if (!(*argv)[0])
-    return;
+    {
+      /* No more non-option arguments. */
+      initial_file = xstrdup("dir");
+      return;
+    }
+
+  /* If first argument begins with '(', add it as if it were given with 
+     '--node'.  This is to support invoking like
+     "info '(emacs)Buffers'".  If it is a well-formed node spec then
+     the rest of the arguments are menu entries to follow, or an
+     index entry.  */
+  if ((*argv)[0][0] == '(')
+    {
+      info_parse_node ((*argv)[0]);
+      if (info_parsed_filename)
+        {
+          initial_file = info_find_fullpath (info_parsed_filename, 0);
+          if (initial_file)
+            {
+              add_pointer_to_array (info_new_reference (initial_file,
+                                                        info_parsed_nodename),
+                                    ref_index, ref_list, ref_slots, 2);
+              /* Remove this argument from the argument list. */
+              memmove (*argv, *argv + 1, *argc-- * sizeof (char *));
+              return;
+            }
+        }
+    }
 
   /* If there are any more arguments, the initial file is the
      dir entry given by the first one. */
     {
-      /* If they say info info, show them info-stnd.texi.  (Get
-         info.texi with info -f info.) */
+      /* If they say info info (or info -O info, etc.), show them 
+         info-stnd.texi.  (Get info.texi with info -f info.) */
       if ((*argv)[0] && mbscasecmp ((*argv)[0], "info") == 0)
         (*argv)[0] = "info-stnd";
 
@@ -267,8 +324,8 @@
         }
     }
 
-  /* Otherwise, we want the dir node.  The only node to be displayed
-     or output will be "Top". */
+  /* Otherwise, use the dir node. */
+  initial_file = xstrdup("dir");
   return;
 }
 
@@ -310,12 +367,7 @@
               int j;
 
               if (!initial_file)
-                {
-                  free (*error);
-                  asprintf (error, _("No file given for node '%s'."),
-                            user_nodenames[i]);
-                  continue;
-                }
+                continue; /* Shouldn't happen. */
 
               /* Check for a node by this name, and if there isn't one
                  look for an inexact match. */
@@ -413,9 +465,16 @@
       free (program);
     }
 
+  /* Default is the "Top" node if there were no other nodes. */
+  if (ref_index == 0 && initial_file)
+    {
+       add_pointer_to_array (info_new_reference (initial_file, "Top"), 
+                             ref_index, ref_list, ref_slots, 2);
+    }
+
   /* If there are arguments remaining, they are the names of menu items
      in sequential info files starting from the first one loaded. */
-  else if (*argv && ref_index > 0)
+  if (*argv && ref_index > 0)
     {
       NODE *initial_node; /* Node to start following menus from. */
       NODE *node_via_menus;
@@ -459,6 +518,7 @@
             }
         }
 
+      fprintf(stderr, "B %p\n", initial_node);
       /* If there are arguments remaining, follow menus inexactly. */
       if (argc != 0)
         {
@@ -883,6 +943,18 @@
       /* If only one match, don't start in a menu of matches. */
       if (ref_index == 1)
         all_matches_p = 0;
+
+      /* --where */
+      if (print_where_p)
+        {
+          int i;
+          if (!ref_list)
+            exit (1);
+
+          for (i = 0; ref_list[i]; i++)
+            printf ("%s\n", ref_list[i]->filename);
+          exit (0);
+        }
     }
   else
     {
@@ -900,57 +972,7 @@
             }
         }
 
-      /* User used "--file". */
-      if (user_filename)
-        {
-          if (!IS_ABSOLUTE(user_filename) && HAS_SLASH(user_filename)
-              && !(user_filename[0] == '.' && IS_SLASH(user_filename[1])))
-            {
-              /* Prefix "./" to the filename to prevent a lookup
-                 in INFOPATH.  */
-              char *s;
-              asprintf (&s, "%s%s", "./", user_filename);
-              free (user_filename);
-              user_filename = s;
-            }
-          if (IS_ABSOLUTE(user_filename) || HAS_SLASH(user_filename))
-            initial_file = info_add_extension (0, user_filename, 0);
-          else
-            initial_file = info_find_fullpath (user_filename, 0);
-
-          if (!initial_file)
-            {
-              if (!filesys_error_number)
-                filesys_error_number = ENOENT;
-              error = filesys_error_string (user_filename, 
-                                            filesys_error_number);
-            }
-          else
-            add_pointer_to_array (info_new_reference (initial_file, "Top"),
-                                  ref_index, ref_list, ref_slots, 2);
-          goto skip_get_initial_file;
-        }
-
-      /* If first argument begins with '(', add it as if it were given with 
-         '--node'.  This is to support invoking like
-         "info '(emacs)Buffers'".  If it is a well-formed node spec then
-         the rest of the arguments are menu entries to follow, or an
-         index entry.  */
-      if (argv[0] && argv[0][0] == '(')
-        {
-          info_parse_node (argv[0]);
-          if (info_parsed_filename)
-            {
-              add_pointer_to_array (info_new_reference (info_parsed_filename,
-                                                        info_parsed_nodename),
-                                    ref_index, ref_list, ref_slots, 2);
-              memmove (argv, argv + 1, argc-- * sizeof (char *));
-              goto skip_get_initial_file;
-            }
-        }
-
       get_initial_file (&argc, &argv, &error);
-skip_get_initial_file:
 
       /* If the user specified `--index-search=STRING', 
          start the info session in the node corresponding
@@ -990,18 +1012,15 @@
         {
           add_initial_nodes (argc, argv, &error);
         }
-    }
 
-  /* --where */
-  if (print_where_p)
-    {
-      int i;
-      if (!ref_list)
-        exit (1);
+      /* --where */
+      if (print_where_p)
+        {
+          if (initial_file)
+            printf ("%s\n", initial_file);
+          exit (0);
+        }
 
-      for (i = 0; ref_list[i]; i++)
-        printf ("%s\n", ref_list[i]->filename);
-      exit (0);
     }
 
   /* --output */
--- texinfo.orig/info/session.c
+++ texinfo/info/session.c
@@ -2815,7 +2815,13 @@
                         entry->label,
                         node_printed_rep (initial_node));
             }
-          return strict ? 0 : initial_node;
+          if (strict)
+            {
+              free_history_node (initial_node);
+              return 0;
+            }
+          else
+            return initial_node;
         }
 
       debug (3, ("node: %s, %s", node->fullpath, node->nodename));
--- texinfo.orig/info/t/node-no-file.sh
+++ texinfo/info/t/node-no-file.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (C) 2014 Free Software Foundation, Inc.
+# Copyright (C) 2014, 2016 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -19,4 +19,4 @@
 
 # Ask for a node without saying which file it's in
 $GINFO --output - --node nodename \
-  2>&1 | grep 'No file given'
+  2>&1 | grep 'Cannot find node'
