LCOV - code coverage report
Current view: top level - bash-4.4.23 - make_cmd.c (source / functions) Hit Total Coverage
Test: cov-sh.info Lines: 271 396 68.4 %
Date: 2020-10-29 14:49:55 Functions: 25 34 73.5 %

          Line data    Source code
       1             : /* make_cmd.c -- Functions for making instances of the various
       2             :    parser constructs. */
       3             : 
       4             : /* Copyright (C) 1989-2009 Free Software Foundation, Inc.
       5             : 
       6             :    This file is part of GNU Bash, the Bourne Again SHell.
       7             : 
       8             :    Bash is free software: you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation, either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    Bash is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "config.h"
      23             : 
      24             : #include <stdio.h>
      25             : #include "bashtypes.h"
      26             : #if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
      27             : #  include <sys/file.h>
      28             : #endif
      29             : #include "filecntl.h"
      30             : #include "bashansi.h"
      31             : #if defined (HAVE_UNISTD_H)
      32             : #  include <unistd.h>
      33             : #endif
      34             : 
      35             : #include "bashintl.h"
      36             : 
      37             : #include "parser.h"
      38             : #include "syntax.h"
      39             : #include "command.h"
      40             : #include "general.h"
      41             : #include "error.h"
      42             : #include "flags.h"
      43             : #include "make_cmd.h"
      44             : #include "dispose_cmd.h"
      45             : #include "execute_cmd.h"
      46             : #include "variables.h"
      47             : #include "subst.h"
      48             : #include "input.h"
      49             : #include "ocache.h"
      50             : #include "externs.h"
      51             : #include "builtins.h"
      52             : 
      53             : #include "builtins/common.h"
      54             : 
      55             : #if defined (JOB_CONTROL)
      56             : #include "jobs.h"
      57             : #endif
      58             : 
      59             : #include "shmbutil.h"
      60             : 
      61             : extern int line_number, current_command_line_count, parser_state;
      62             : extern int last_command_exit_value;
      63             : extern int shell_initialized;
      64             : extern int rpm_requires;
      65             : 
      66             : int here_doc_first_line = 0;
      67             : 
      68             : static char *alphabet_set = "abcdefghijklmnopqrstuvwxyz"
      69             :                             "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      70             : 
      71             : /* Object caching */
      72             : sh_obj_cache_t wdcache = {0, 0, 0};
      73             : sh_obj_cache_t wlcache = {0, 0, 0};
      74             : 
      75             : #define WDCACHESIZE     128
      76             : #define WLCACHESIZE     128
      77             : 
      78             : static COMMAND *make_for_or_select __P((enum command_type, WORD_DESC *, WORD_LIST *, COMMAND *, int));
      79             : #if defined (ARITH_FOR_COMMAND)
      80             : static WORD_LIST *make_arith_for_expr __P((char *));
      81             : #endif
      82             : static COMMAND *make_until_or_while __P((enum command_type, COMMAND *, COMMAND *));
      83             : 
      84             : void
      85     9542926 : cmd_init ()
      86             : {
      87     9542926 :   ocache_create (wdcache, WORD_DESC, WDCACHESIZE);
      88     9542926 :   ocache_create (wlcache, WORD_LIST, WLCACHESIZE);
      89     9542926 : }
      90             : 
      91             : WORD_DESC *
      92  1693158040 : alloc_word_desc ()
      93             : {
      94  1693158040 :   WORD_DESC *temp;
      95             : 
      96  1693158040 :   ocache_alloc (wdcache, WORD_DESC, temp);
      97  1693158040 :   temp->flags = 0;
      98  1693158040 :   temp->word = 0;
      99  1693158040 :   return temp;
     100             : }
     101             : 
     102             : WORD_DESC *
     103   771689644 : make_bare_word (string)
     104             :      const char *string;
     105             : {
     106   771689644 :   WORD_DESC *temp;
     107             : 
     108   771689644 :   temp = alloc_word_desc ();
     109             : 
     110   771689644 :   if (*string)
     111   771689559 :     temp->word = savestring (string);
     112             :   else
     113             :     {
     114          85 :       temp->word = (char *)xmalloc (1);
     115          85 :       temp->word[0] = '\0';
     116             :     }
     117             : 
     118   771689644 :   return (temp);
     119             : }
     120             : 
     121             : WORD_DESC *
     122     5658363 : make_word_flags (w, string)
     123             :      WORD_DESC *w;
     124             :      const char *string;
     125             : {
     126     5658363 :   register int i;
     127     5658363 :   size_t slen;
     128     5658363 :   DECLARE_MBSTATE;
     129             : 
     130     5658363 :   i = 0;
     131     5658363 :   slen = strlen (string);
     132     5658363 :   while (i < slen)
     133             :     {
     134     9034014 :       switch (string[i])
     135             :         {
     136        1806 :         case '$':
     137        1806 :           w->flags |= W_HASDOLLAR;
     138        1806 :           break;
     139             :         case '\\':
     140             :           break;        /* continue the loop */
     141        4439 :         case '\'':
     142             :         case '`':
     143             :         case '"':
     144        4439 :           w->flags |= W_QUOTED;
     145        4439 :           break;
     146             :         }
     147             : 
     148    23726391 :       ADVANCE_CHAR (string, slen, i);
     149             :     }
     150             : 
     151     5658363 :   return (w);
     152             : }
     153             : 
     154             : WORD_DESC *
     155     5656591 : make_word (string)
     156             :      const char *string;
     157             : {
     158     5656591 :   WORD_DESC *temp;
     159             : 
     160     5656591 :   temp = make_bare_word (string);
     161     5656591 :   return (make_word_flags (temp, string));
     162             : }
     163             : 
     164             : WORD_DESC *
     165           0 : make_word_from_token (token)
     166             :      int token;
     167             : {
     168           0 :   char tokenizer[2];
     169             : 
     170           0 :   tokenizer[0] = token;
     171           0 :   tokenizer[1] = '\0';
     172             : 
     173           0 :   return (make_word (tokenizer));
     174             : }
     175             : 
     176             : WORD_LIST *
     177  1522077523 : make_word_list (word, wlink)
     178             :      WORD_DESC *word;
     179             :      WORD_LIST *wlink;
     180             : {
     181  1522077523 :   WORD_LIST *temp;
     182             : 
     183  1522077523 :   ocache_alloc (wlcache, WORD_LIST, temp);
     184             : 
     185  1522077523 :   temp->word = word;
     186  1522077523 :   temp->next = wlink;
     187  1522077523 :   return (temp);
     188             : }
     189             : 
     190             : COMMAND *
     191           0 : make_command (type, pointer)
     192             :      enum command_type type;
     193             :      SIMPLE_COM *pointer;
     194             : {
     195   218732018 :   COMMAND *temp;
     196             : 
     197           0 :   temp = (COMMAND *)xmalloc (sizeof (COMMAND));
     198   218732018 :   temp->type = type;
     199   218732018 :   temp->value.Simple = pointer;
     200   218732018 :   temp->value.Simple->flags = temp->flags = 0;
     201   218732018 :   temp->redirects = (REDIRECT *)NULL;
     202   218732018 :   return (temp);
     203             : }
     204             : 
     205             : COMMAND *
     206    86115900 : command_connect (com1, com2, connector)
     207             :      COMMAND *com1, *com2;
     208             :      int connector;
     209             : {
     210    86115900 :   CONNECTION *temp;
     211             : 
     212    86115900 :   temp = (CONNECTION *)xmalloc (sizeof (CONNECTION));
     213    86115900 :   temp->connector = connector;
     214    86115900 :   temp->first = com1;
     215    86115900 :   temp->second = com2;
     216    86115900 :   return (make_command (cm_connection, (SIMPLE_COM *)temp));
     217             : }
     218             : 
     219             : static COMMAND *
     220     9542934 : make_for_or_select (type, name, map_list, action, lineno)
     221             :      enum command_type type;
     222             :      WORD_DESC *name;
     223             :      WORD_LIST *map_list;
     224             :      COMMAND *action;
     225             :      int lineno;
     226             : {
     227     9542934 :   FOR_COM *temp;
     228             : 
     229     9542934 :   temp = (FOR_COM *)xmalloc (sizeof (FOR_COM));
     230     9542934 :   temp->flags = 0;
     231     9542934 :   temp->name = name;
     232     9542934 :   temp->line = lineno;
     233     9542934 :   temp->map_list = map_list;
     234     9542934 :   temp->action = action;
     235     9542934 :   return (make_command (type, (SIMPLE_COM *)temp));
     236             : }
     237             : 
     238             : COMMAND *
     239     9542934 : make_for_command (name, map_list, action, lineno)
     240             :      WORD_DESC *name;
     241             :      WORD_LIST *map_list;
     242             :      COMMAND *action;
     243             :      int lineno;
     244             : {
     245     9542934 :   return (make_for_or_select (cm_for, name, map_list, action, lineno));
     246             : }
     247             : 
     248             : COMMAND *
     249           0 : make_select_command (name, map_list, action, lineno)
     250             :      WORD_DESC *name;
     251             :      WORD_LIST *map_list;
     252             :      COMMAND *action;
     253             :      int lineno;
     254             : {
     255             : #if defined (SELECT_COMMAND)
     256           0 :   return (make_for_or_select (cm_select, name, map_list, action, lineno));
     257             : #else
     258             :   last_command_exit_value = 2;
     259             :   return ((COMMAND *)NULL);
     260             : #endif
     261             : }
     262             : 
     263             : #if defined (ARITH_FOR_COMMAND)
     264             : static WORD_LIST *
     265           0 : make_arith_for_expr (s)
     266             :      char *s;
     267             : {
     268           0 :   WORD_LIST *result;
     269           0 :   WORD_DESC *wd;
     270             : 
     271           0 :   if (s == 0 || *s == '\0')
     272             :     return ((WORD_LIST *)NULL);
     273           0 :   wd = make_word (s);
     274           0 :   wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_DQUOTE; /* no word splitting or globbing */
     275             : #if defined (PROCESS_SUBSTITUTION)
     276           0 :   wd->flags |= W_NOPROCSUB;  /* no process substitution */
     277             : #endif
     278           0 :   result = make_word_list (wd, (WORD_LIST *)NULL);
     279           0 :   return result;
     280             : }
     281             : #endif
     282             : 
     283             : /* Note that this function calls dispose_words on EXPRS, since it doesn't
     284             :    use the word list directly.  We free it here rather than at the caller
     285             :    because no other function in this file requires that the caller free
     286             :    any arguments. */
     287             : COMMAND *
     288           0 : make_arith_for_command (exprs, action, lineno)
     289             :      WORD_LIST *exprs;
     290             :      COMMAND *action;
     291             :      int lineno;
     292             : {
     293             : #if defined (ARITH_FOR_COMMAND)
     294           0 :   ARITH_FOR_COM *temp;
     295           0 :   WORD_LIST *init, *test, *step;
     296           0 :   char *s, *t, *start;
     297           0 :   int nsemi, i;
     298             : 
     299           0 :   init = test = step = (WORD_LIST *)NULL;
     300             :   /* Parse the string into the three component sub-expressions. */
     301           0 :   start = t = s = exprs->word->word;
     302           0 :   for (nsemi = 0; ;)
     303             :     {
     304             :       /* skip whitespace at the start of each sub-expression. */
     305           0 :       while (whitespace (*s))
     306           0 :         s++;
     307           0 :       start = s;
     308             :       /* skip to the semicolon or EOS */
     309           0 :       i = skip_to_delim (start, 0, ";", SD_NOJMP|SD_NOPROCSUB);
     310           0 :       s = start + i;
     311             : 
     312           0 :       t = (i > 0) ? substring (start, 0, i) : (char *)NULL;
     313             : 
     314           0 :       nsemi++;
     315           0 :       switch (nsemi)
     316             :         {
     317           0 :         case 1:
     318           0 :           init = make_arith_for_expr (t);
     319           0 :           break;
     320           0 :         case 2:
     321           0 :           test = make_arith_for_expr (t);
     322           0 :           break;
     323           0 :         case 3:
     324           0 :           step = make_arith_for_expr (t);
     325           0 :           break;
     326             :         }
     327             : 
     328           0 :       FREE (t);
     329           0 :       if (*s == '\0')
     330             :         break;
     331           0 :       s++;      /* skip over semicolon */
     332             :     }
     333             : 
     334           0 :   if (nsemi != 3)
     335             :     {
     336           0 :       if (nsemi < 3)
     337           0 :         parser_error (lineno, _("syntax error: arithmetic expression required"));
     338             :       else
     339           0 :         parser_error (lineno, _("syntax error: `;' unexpected"));
     340           0 :       parser_error (lineno, _("syntax error: `((%s))'"), exprs->word->word);
     341           0 :       free (init);
     342           0 :       free (test);
     343           0 :       free (step);
     344           0 :       last_command_exit_value = 2;
     345           0 :       return ((COMMAND *)NULL);
     346             :     }
     347             : 
     348           0 :   temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
     349           0 :   temp->flags = 0;
     350           0 :   temp->line = lineno;
     351           0 :   temp->init = init ? init : make_arith_for_expr ("1");
     352           0 :   temp->test = test ? test : make_arith_for_expr ("1");
     353           0 :   temp->step = step ? step : make_arith_for_expr ("1");
     354           0 :   temp->action = action;
     355             : 
     356           0 :   dispose_words (exprs);
     357           0 :   return (make_command (cm_arith_for, (SIMPLE_COM *)temp));
     358             : #else
     359             :   dispose_words (exprs);
     360             :   last_command_exit_value = 2;
     361             :   return ((COMMAND *)NULL);
     362             : #endif /* ARITH_FOR_COMMAND */
     363             : }
     364             : 
     365             : COMMAND *
     366    18766112 : make_group_command (command)
     367             :      COMMAND *command;
     368             : {
     369    18766112 :   GROUP_COM *temp;
     370             : 
     371    18766112 :   temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
     372    18766112 :   temp->command = command;
     373    18766112 :   return (make_command (cm_group, (SIMPLE_COM *)temp));
     374             : }
     375             : 
     376             : COMMAND *
     377    15244939 : make_case_command (word, clauses, lineno)
     378             :      WORD_DESC *word;
     379             :      PATTERN_LIST *clauses;
     380             :      int lineno;
     381             : {
     382    15244939 :   CASE_COM *temp;
     383             : 
     384    15244939 :   temp = (CASE_COM *)xmalloc (sizeof (CASE_COM));
     385    15244939 :   temp->flags = 0;
     386    15244939 :   temp->line = lineno;
     387    15244939 :   temp->word = word;
     388    15244939 :   temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *);
     389    15244939 :   return (make_command (cm_case, (SIMPLE_COM *)temp));
     390             : }
     391             : 
     392             : PATTERN_LIST *
     393    49355077 : make_pattern_list (patterns, action)
     394             :      WORD_LIST *patterns;
     395             :      COMMAND *action;
     396             : {
     397    49355077 :   PATTERN_LIST *temp;
     398             : 
     399    49355077 :   temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
     400    49355077 :   temp->patterns = REVERSE_LIST (patterns, WORD_LIST *);
     401    49355077 :   temp->action = action;
     402    49355077 :   temp->next = NULL;
     403    49355077 :   temp->flags = 0;
     404    49355077 :   return (temp);
     405             : }
     406             : 
     407             : COMMAND *
     408    68460651 : make_if_command (test, true_case, false_case)
     409             :      COMMAND *test, *true_case, *false_case;
     410             : {
     411    68460651 :   IF_COM *temp;
     412             : 
     413    68460651 :   temp = (IF_COM *)xmalloc (sizeof (IF_COM));
     414    68460651 :   temp->flags = 0;
     415    68460651 :   temp->test = test;
     416    68460651 :   temp->true_case = true_case;
     417    68460651 :   temp->false_case = false_case;
     418    68460651 :   return (make_command (cm_if, (SIMPLE_COM *)temp));
     419             : }
     420             : 
     421             : static COMMAND *
     422     1837387 : make_until_or_while (which, test, action)
     423             :      enum command_type which;
     424             :      COMMAND *test, *action;
     425             : {
     426     1837387 :   WHILE_COM *temp;
     427             : 
     428     1837387 :   temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
     429     1837387 :   temp->flags = 0;
     430     1837387 :   temp->test = test;
     431     1837387 :   temp->action = action;
     432     1837387 :   return (make_command (which, (SIMPLE_COM *)temp));
     433             : }
     434             : 
     435             : COMMAND *
     436     1837387 : make_while_command (test, action)
     437             :      COMMAND *test, *action;
     438             : {
     439     1837387 :   return (make_until_or_while (cm_while, test, action));
     440             : }
     441             : 
     442             : COMMAND *
     443           0 : make_until_command (test, action)
     444             :      COMMAND *test, *action;
     445             : {
     446           0 :   return (make_until_or_while (cm_until, test, action));
     447             : }
     448             : 
     449             : COMMAND *
     450           0 : make_arith_command (exp)
     451             :      WORD_LIST *exp;
     452             : {
     453             : #if defined (DPAREN_ARITHMETIC)
     454           0 :   COMMAND *command;
     455           0 :   ARITH_COM *temp;
     456             : 
     457           0 :   command = (COMMAND *)xmalloc (sizeof (COMMAND));
     458           0 :   command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
     459             : 
     460           0 :   temp->flags = 0;
     461           0 :   temp->line = line_number;
     462           0 :   temp->exp = exp;
     463             : 
     464           0 :   command->type = cm_arith;
     465           0 :   command->redirects = (REDIRECT *)NULL;
     466           0 :   command->flags = 0;
     467             : 
     468           0 :   return (command);
     469             : #else
     470             :   last_command_exit_value = 2;
     471             :   return ((COMMAND *)NULL);
     472             : #endif
     473             : }
     474             : 
     475             : #if defined (COND_COMMAND)
     476             : struct cond_com *
     477          72 : make_cond_node (type, op, left, right)
     478             :      int type;
     479             :      WORD_DESC *op;
     480             :      struct cond_com *left, *right;
     481             : {
     482          72 :   COND_COM *temp;
     483             : 
     484          72 :   temp = (COND_COM *)xmalloc (sizeof (COND_COM));
     485          72 :   temp->flags = 0;
     486          72 :   temp->line = line_number;
     487          72 :   temp->type = type;
     488          72 :   temp->op = op;
     489          72 :   temp->left = left;
     490          72 :   temp->right = right;
     491             : 
     492          72 :   return (temp);
     493             : }
     494             : #endif
     495             : 
     496             : COMMAND *
     497          72 : make_cond_command (cond_node)
     498             :      COND_COM *cond_node;
     499             : {
     500             : #if defined (COND_COMMAND)
     501          72 :   COMMAND *command;
     502             : 
     503          72 :   command = (COMMAND *)xmalloc (sizeof (COMMAND));
     504          72 :   command->value.Cond = cond_node;
     505             : 
     506          72 :   command->type = cm_cond;
     507          72 :   command->redirects = (REDIRECT *)NULL;
     508          72 :   command->flags = 0;
     509          72 :   command->line = cond_node ? cond_node->line : 0;
     510             : 
     511          72 :   return (command);
     512             : #else
     513             :   last_command_exit_value = 2;
     514             :   return ((COMMAND *)NULL);
     515             : #endif
     516             : }
     517             : 
     518             : COMMAND *
     519   281724804 : make_bare_simple_command ()
     520             : {
     521   281724804 :   COMMAND *command;
     522   281724804 :   SIMPLE_COM *temp;
     523             : 
     524   281724804 :   command = (COMMAND *)xmalloc (sizeof (COMMAND));
     525   281724804 :   command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
     526             : 
     527   281724804 :   temp->flags = 0;
     528   281724804 :   temp->line = line_number;
     529   281724804 :   temp->words = (WORD_LIST *)NULL;
     530   281724804 :   temp->redirects = (REDIRECT *)NULL;
     531             : 
     532   281724804 :   command->type = cm_simple;
     533   281724804 :   command->redirects = (REDIRECT *)NULL;
     534   281724804 :   command->flags = 0;
     535             : 
     536   281724804 :   return (command);
     537             : }
     538             : 
     539             : /* Return a command which is the connection of the word or redirection
     540             :    in ELEMENT, and the command * or NULL in COMMAND. */
     541             : COMMAND *
     542   716132211 : make_simple_command (element, command)
     543             :      ELEMENT element;
     544             :      COMMAND *command;
     545             : {
     546             :   /* If we are starting from scratch, then make the initial command
     547             :      structure.  Also note that we have to fill in all the slots, since
     548             :      malloc doesn't return zeroed space. */
     549   716132211 :   if (command == 0)
     550             :     {
     551   281724787 :       command = make_bare_simple_command ();
     552   281724787 :       parser_state |= PST_REDIRLIST;
     553             :     }
     554             : 
     555   716132211 :   if (element.word)
     556             :     {
     557   699333905 :       command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
     558   699333905 :       parser_state &= ~PST_REDIRLIST;
     559             :     }
     560    16798306 :   else if (element.redirect)
     561             :     {
     562             :       REDIRECT *r = element.redirect;
     563             :       /* Due to the way <> is implemented, there may be more than a single
     564             :          redirection in element.redirect.  We just follow the chain as far
     565             :          as it goes, and hook onto the end. */
     566    16798041 :       while (r->next)
     567             :         r = r->next;
     568    16798041 :       r->next = command->value.Simple->redirects;
     569    16798041 :       command->value.Simple->redirects = element.redirect;
     570             :     }
     571             : 
     572   716132211 :   return (command);
     573             : }
     574             : 
     575             : /* Because we are Bourne compatible, we read the input for this
     576             :    << or <<- redirection now, from wherever input is coming from.
     577             :    We store the input read into a WORD_DESC.  Replace the text of
     578             :    the redirectee.word with the new input text.  If <<- is on,
     579             :    then remove leading TABS from each line. */
     580             : void
     581         285 : make_here_document (temp, lineno)
     582             :      REDIRECT *temp;
     583             :      int lineno;
     584             : {
     585         285 :   int kill_leading, redir_len;
     586         285 :   char *redir_word, *document, *full_line;
     587         285 :   int document_index, document_size, delim_unquoted;
     588             : 
     589         285 :   if (temp->instruction != r_deblank_reading_until &&
     590             :       temp->instruction != r_reading_until)
     591             :     {
     592           0 :       internal_error (_("make_here_document: bad instruction type %d"), temp->instruction);
     593           0 :       return;
     594             :     }
     595             : 
     596         285 :   kill_leading = temp->instruction == r_deblank_reading_until;
     597             : 
     598         285 :   document = (char *)NULL;
     599         285 :   document_index = document_size = 0;
     600             : 
     601             :   /* Quote removal is the only expansion performed on the delimiter
     602             :      for here documents, making it an extremely special case. */
     603         285 :   redir_word = string_quote_removal (temp->redirectee.filename->word, 0);
     604             : 
     605             :   /* redirection_expand will return NULL if the expansion results in
     606             :      multiple words or no words.  Check for that here, and just abort
     607             :      this here document if it does. */
     608         285 :   if (redir_word)
     609         285 :     redir_len = strlen (redir_word);
     610             :   else
     611             :     {
     612           0 :       temp->here_doc_eof = (char *)xmalloc (1);
     613           0 :       temp->here_doc_eof[0] = '\0';
     614           0 :       goto document_done;
     615             :     }
     616             : 
     617         285 :   free (temp->redirectee.filename->word);
     618         285 :   temp->here_doc_eof = redir_word;
     619             : 
     620             :   /* Read lines from wherever lines are coming from.
     621             :      For each line read, if kill_leading, then kill the
     622             :      leading tab characters.
     623             :      If the line matches redir_word exactly, then we have
     624             :      manufactured the document.  Otherwise, add the line to the
     625             :      list of lines in the document. */
     626             : 
     627             :   /* If the here-document delimiter was quoted, the lines should
     628             :      be read verbatim from the input.  If it was not quoted, we
     629             :      need to perform backslash-quoted newline removal. */
     630         285 :   delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
     631        1789 :   while (full_line = read_secondary_line (delim_unquoted))
     632             :     {
     633        1504 :       register char *line;
     634        1504 :       int len;
     635             : 
     636        1504 :       here_doc_first_line = 0;
     637        1504 :       line = full_line;
     638        1504 :       line_number++;
     639             : 
     640             :       /* If set -v is in effect, echo the line read.  read_secondary_line/
     641             :          read_a_line leaves the newline at the end, so don't print another. */
     642        1504 :       if (echo_input_at_read)
     643           0 :         fprintf (stderr, "%s", line);
     644             : 
     645        1504 :       if (kill_leading && *line)
     646             :         {
     647             :           /* Hack:  To be compatible with some Bourne shells, we
     648             :              check the word before stripping the whitespace.  This
     649             :              is a hack, though. */
     650           0 :           if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
     651           0 :             goto document_done;
     652             : 
     653           0 :           while (*line == '\t')
     654           0 :             line++;
     655             :         }
     656             : 
     657        1504 :       if (*line == 0)
     658             :         continue;
     659             : 
     660        1504 :       if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
     661           0 :         goto document_done;
     662             : 
     663        1504 :       len = strlen (line);
     664        1504 :       if (len + document_index >= document_size)
     665             :         {
     666         293 :           document_size = document_size ? 2 * (document_size + len) : len + 2;
     667         293 :           document = (char *)xrealloc (document, document_size);
     668             :         }
     669             : 
     670             :       /* len is guaranteed to be > 0 because of the check for line
     671             :          being an empty string before the call to strlen. */
     672        1504 :       FASTCOPY (line, document + document_index, len);
     673        1504 :       document_index += len;
     674             :     }
     675             : 
     676         285 :   if (full_line == 0)
     677         285 :     internal_warning (_("here-document at line %d delimited by end-of-file (wanted `%s')"), lineno, redir_word);
     678             : 
     679         285 : document_done:
     680         285 :   if (document)
     681          98 :     document[document_index] = '\0';
     682             :   else
     683             :     {
     684         187 :       document = (char *)xmalloc (1);
     685         187 :       document[0] = '\0';
     686             :     }
     687         285 :   temp->redirectee.filename->word = document;
     688         285 :   here_doc_first_line = 0;
     689             : }
     690             : 
     691             : /* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION.
     692             :    INSTRUCTION is the instruction type, SOURCE is a file descriptor,
     693             :    and DEST is a file descriptor or a WORD_DESC *. */
     694             : REDIRECT *
     695    16799635 : make_redirection (source, instruction, dest_and_filename, flags)
     696             :      REDIRECTEE source;
     697             :      enum r_instruction instruction;
     698             :      REDIRECTEE dest_and_filename;
     699             :      int flags;
     700             : {
     701    16799635 :   REDIRECT *temp;
     702    16799635 :   WORD_DESC *w;
     703    16799635 :   int wlen;
     704    16799635 :   intmax_t lfd;
     705             : 
     706    16799635 :   temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));
     707             : 
     708             :   /* First do the common cases. */
     709    16799635 :   temp->redirector = source;
     710    16799635 :   temp->redirectee = dest_and_filename;
     711    16799635 :   temp->here_doc_eof = 0;
     712    16799635 :   temp->instruction = instruction;
     713    16799635 :   temp->flags = 0;
     714    16799635 :   temp->rflags = flags;
     715    16799635 :   temp->next = (REDIRECT *)NULL;
     716             : 
     717    16799635 :   switch (instruction)
     718             :     {
     719             : 
     720     7646448 :     case r_output_direction:            /* >foo */
     721             :     case r_output_force:                /* >| foo */
     722             :     case r_err_and_out:                 /* &>filename */
     723     7646448 :       temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
     724     7646448 :       break;
     725             : 
     726     3500833 :     case r_appending_to:                /* >>foo */
     727             :     case r_append_err_and_out:          /* &>> filename */
     728     3500833 :       temp->flags = O_APPEND | O_WRONLY | O_CREAT;
     729     3500833 :       break;
     730             : 
     731             :     case r_input_direction:             /* <foo */
     732             :     case r_inputa_direction:            /* foo & makes this. */
     733             :       temp->flags = O_RDONLY;
     734             :       break;
     735             : 
     736         103 :     case r_input_output:                /* <>foo */
     737         103 :       temp->flags = O_RDWR | O_CREAT;
     738         103 :       break;
     739             : 
     740             :     case r_deblank_reading_until:       /* <<-foo */
     741             :     case r_reading_until:               /* << foo */
     742             :     case r_reading_string:              /* <<< foo */
     743             :     case r_close_this:                  /* <&- */
     744             :     case r_duplicating_input:           /* 1<&2 */
     745             :     case r_duplicating_output:          /* 1>&2 */
     746             :       break;
     747             : 
     748             :     /* the parser doesn't pass these. */
     749             :     case r_move_input:                  /* 1<&2- */
     750             :     case r_move_output:                 /* 1>&2- */
     751             :     case r_move_input_word:             /* 1<&$foo- */
     752             :     case r_move_output_word:            /* 1>&$foo- */
     753             :       break;
     754             : 
     755             :     /* The way the lexer works we have to do this here. */
     756        5408 :     case r_duplicating_input_word:      /* 1<&$foo */
     757             :     case r_duplicating_output_word:     /* 1>&$foo */
     758        5408 :       w = dest_and_filename.filename;
     759        5408 :       wlen = strlen (w->word) - 1;
     760        5408 :       if (w->word[wlen] == '-')              /* Yuck */
     761             :         {
     762           9 :           w->word[wlen] = '\0';
     763           9 :           if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd)
     764             :             {
     765           9 :               dispose_word (w);
     766           9 :               temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output;
     767           9 :               temp->redirectee.dest = lfd;
     768             :             }
     769             :           else
     770           0 :             temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word;
     771             :         }
     772             :           
     773             :       break;
     774             : 
     775           0 :     default:
     776           0 :       programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction);
     777           0 :       abort ();
     778    16799635 :       break;
     779             :     }
     780    16799635 :   return (temp);
     781             : }
     782             : 
     783             : static void
     784           0 : output_requirement (deptype, filename)
     785             : const char *deptype;
     786             : char *filename;
     787             : {
     788           0 :   if (strchr(filename, '$') || (filename[0] != '/' && strchr(filename, '/')))
     789             :     return;
     790             : 
     791             :   /*
     792             :       if the executable is called via variable substitution we can
     793             :       not dermine what it is at compile time.
     794             : 
     795             :       if the executable consists only of characters not in the
     796             :       alphabet we do not consider it a dependency just an artifact
     797             :       of shell parsing (ex "exec < ${infile}").
     798             :   */
     799             : 
     800           0 :   if (strpbrk(filename, alphabet_set))
     801           0 :     printf ("%s(%s)\n", deptype, filename);
     802             : }
     803             : 
     804             : COMMAND *
     805    18763882 : make_function_def (name, command, lineno, lstart)
     806             :      WORD_DESC *name;
     807             :      COMMAND *command;
     808             :      int lineno, lstart;
     809             : {
     810    18763882 :   FUNCTION_DEF *temp;
     811             : #if defined (ARRAY_VARS)
     812    18763882 :   SHELL_VAR *bash_source_v;
     813    18763882 :   ARRAY *bash_source_a;
     814             : #endif
     815             : 
     816    18763882 :   temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
     817    18763882 :   temp->command = command;
     818    18763882 :   temp->name = name;
     819    18763882 :   temp->line = lineno;
     820    18763882 :   temp->flags = 0;
     821    18763882 :   command->line = lstart;
     822             : 
     823             :   /* Information used primarily for debugging. */
     824    18763882 :   temp->source_file = 0;
     825             : #if defined (ARRAY_VARS)
     826    18763882 :   GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
     827    18763882 :   if (bash_source_a && array_num_elements (bash_source_a) > 0)
     828          54 :     temp->source_file = array_reference (bash_source_a, 0);
     829             : #endif
     830             :   /* Assume that shell functions without a source file before the shell is
     831             :      initialized come from the environment.  Otherwise default to "main"
     832             :      (usually functions being defined interactively) */
     833    18763882 :   if (temp->source_file == 0)
     834    18763828 :     temp->source_file = shell_initialized ? "main" : "environment";
     835             : 
     836             : #if defined (DEBUGGER)
     837    18763882 :   bind_function_def (name->word, temp);
     838             : #endif
     839             : 
     840    18763882 :   temp->source_file = temp->source_file ? savestring (temp->source_file) : 0;
     841             : 
     842    18763882 :   if (rpm_requires) {
     843             :     /* Each function is possibly required, which is, er, provided.
     844             :      * I need to know function names in order to implement strong
     845             :      * self-requires elimination in /usr/lib/rpm/shell.req.  Just about
     846             :      * the only way to achieve this without breaking "--rpm-requires"
     847             :      * compatibility is to spit them here as they go.
     848             :      *
     849             :      * Also note that another "function" output in clean_simple_command()
     850             :      * is not much useful since it only means that a function is defined
     851             :      * in the very same file before being used (shell have seen it while
     852             :      * parsing the script).  My point is that it makes no sense to resolve
     853             :      * function requirements -- functions are simply "provided" by its nature.
     854             :      *
     855             :      *    -- at@altlinux
     856             :      */
     857           0 :     output_requirement ("function", name->word);
     858             :   }
     859             : 
     860    18763882 :   return (make_command (cm_function_def, (SIMPLE_COM *)temp));
     861             : }
     862             : 
     863             : COMMAND *
     864         213 : make_subshell_command (command)
     865             :      COMMAND *command;
     866             : {
     867         213 :   SUBSHELL_COM *temp;
     868             : 
     869         213 :   temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
     870         213 :   temp->command = command;
     871         213 :   temp->flags = CMD_WANT_SUBSHELL;
     872         213 :   return (make_command (cm_subshell, (SIMPLE_COM *)temp));
     873             : }
     874             : 
     875             : COMMAND *
     876           0 : make_coproc_command (name, command)
     877             :      char *name;
     878             :      COMMAND *command;
     879             : {
     880           0 :   COPROC_COM *temp;
     881             : 
     882           0 :   temp = (COPROC_COM *)xmalloc (sizeof (COPROC_COM));
     883           0 :   temp->name = savestring (name);
     884           0 :   temp->command = command;
     885           0 :   temp->flags = CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
     886           0 :   return (make_command (cm_coproc, (SIMPLE_COM *)temp));
     887             : }
     888             : 
     889             : /* Reverse the word list and redirection list in the simple command
     890             :    has just been parsed.  It seems simpler to do this here the one
     891             :    time then by any other method that I can think of. */
     892             : COMMAND *
     893   281712394 : clean_simple_command (command)
     894             :      COMMAND *command;
     895             : {
     896   281712394 :   if (command->type != cm_simple)
     897           0 :     command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0);
     898             :   else
     899             :     {
     900   563424788 :       command->value.Simple->words =
     901   281712394 :         REVERSE_LIST (command->value.Simple->words, WORD_LIST *);
     902   281712394 :       command->value.Simple->redirects =
     903   281712394 :         REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
     904             :     }
     905             : 
     906   281712394 :   parser_state &= ~PST_REDIRLIST;
     907             : 
     908   281712394 :   if (rpm_requires && command->value.Simple->words)
     909             :     {
     910           0 :       WORD_LIST *words = command->value.Simple->words;
     911           0 :       const char *cmd = words->word->word;
     912             : 
     913             :       /* skip LC_* assignments */
     914           0 :       while (words->next && assignment (cmd, 0))
     915             :         {
     916           0 :           if (strncmp (cmd, "LC_", 3) != 0)
     917             :             break;
     918           0 :           words = words->next;
     919           0 :           cmd = words->word->word;
     920             :         }
     921             : 
     922           0 :       if (!assignment (cmd, 0))
     923             :         {
     924           0 :           struct builtin *b = builtin_address_internal (cmd, 0);
     925           0 :           if (b)
     926             :             {
     927             :               /* exec-like builtin with an argument */
     928           0 :               if ((b->flags & REQUIRES_BUILTIN) && words->next)
     929             :                 {
     930           0 :                   words = words->next;
     931           0 :                   cmd = words->word->word;
     932           0 :                   output_requirement ("executable", cmd);
     933             :                 }
     934             :             }
     935             :           else
     936             :             {
     937           0 :               if (find_function (cmd) || find_function_def (cmd))
     938           0 :                 output_requirement ("function", cmd);
     939             :               else
     940           0 :                 output_requirement ("executable", cmd);
     941             :             }
     942             :         }
     943             :     } /* rpm_requires */
     944             : 
     945   281712394 :   return (command);
     946             : }
     947             : 
     948             : /* The Yacc grammar productions have a problem, in that they take a
     949             :    list followed by an ampersand (`&') and do a simple command connection,
     950             :    making the entire list effectively asynchronous, instead of just
     951             :    the last command.  This means that when the list is executed, all
     952             :    the commands have stdin set to /dev/null when job control is not
     953             :    active, instead of just the last.  This is wrong, and needs fixing
     954             :    up.  This function takes the `&' and applies it to the last command
     955             :    in the list.  This is done only for lists connected by `;'; it makes
     956             :    `;' bind `tighter' than `&'. */
     957             : COMMAND *
     958       10369 : connect_async_list (command, command2, connector)
     959             :      COMMAND *command, *command2;
     960             :      int connector;
     961             : {
     962       10369 :   COMMAND *t, *t1, *t2;
     963             : 
     964       10369 :   t1 = command;
     965       10369 :   t = command->value.Connection->second;
     966             : 
     967       10369 :   if (!t || (command->flags & CMD_WANT_SUBSHELL) ||
     968       10369 :       command->value.Connection->connector != ';')
     969             :     {
     970        7084 :       t = command_connect (command, command2, connector);
     971        7084 :       return t;
     972             :     }
     973             : 
     974             :   /* This is just defensive programming.  The Yacc precedence rules
     975             :      will generally hand this function a command where t points directly
     976             :      to the command we want (e.g. given a ; b ; c ; d &, t1 will point
     977             :      to the `a ; b ; c' list and t will be the `d').  We only want to do
     978             :      this if the list is not being executed as a unit in the background
     979             :      with `( ... )', so we have to check for CMD_WANT_SUBSHELL.  That's
     980             :      the only way to tell. */
     981        3285 :   while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection &&
     982         582 :          t->value.Connection->connector == ';')
     983             :     {
     984           0 :       t1 = t;
     985           0 :       t = t->value.Connection->second;
     986             :     }
     987             :   /* Now we have t pointing to the last command in the list, and
     988             :      t1->value.Connection->second == t. */
     989        3285 :   t2 = command_connect (t, command2, connector);
     990        3285 :   t1->value.Connection->second = t2;
     991        3285 :   return command;
     992             : }

Generated by: LCOV version 1.14.0.6.4058