Home | History | Annotate | Line # | Download | only in sh
nodes.c.pat revision 1.14
      1  1.14       kre /*	$NetBSD: nodes.c.pat,v 1.14 2018/06/22 11:04:55 kre Exp $	*/
      2   1.6       cgd 
      3   1.1       cgd /*-
      4   1.4       jtc  * Copyright (c) 1991, 1993
      5   1.4       jtc  *	The Regents of the University of California.  All rights reserved.
      6   1.1       cgd  *
      7   1.1       cgd  * This code is derived from software contributed to Berkeley by
      8   1.1       cgd  * Kenneth Almquist.
      9   1.1       cgd  *
     10   1.1       cgd  * Redistribution and use in source and binary forms, with or without
     11   1.1       cgd  * modification, are permitted provided that the following conditions
     12   1.1       cgd  * are met:
     13   1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     14   1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     15   1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     17   1.1       cgd  *    documentation and/or other materials provided with the distribution.
     18  1.11       agc  * 3. Neither the name of the University nor the names of its contributors
     19   1.1       cgd  *    may be used to endorse or promote products derived from this software
     20   1.1       cgd  *    without specific prior written permission.
     21   1.1       cgd  *
     22   1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23   1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24   1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25   1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26   1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27   1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28   1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29   1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30   1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31   1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32   1.1       cgd  * SUCH DAMAGE.
     33   1.1       cgd  *
     34   1.7  christos  *	@(#)nodes.c.pat	8.2 (Berkeley) 5/4/95
     35   1.1       cgd  */
     36   1.1       cgd 
     37   1.7  christos #include <stdlib.h>
     38  1.14       kre #include <stddef.h>
     39  1.14       kre 
     40   1.1       cgd /*
     41   1.1       cgd  * Routine for dealing with parsed shell commands.
     42   1.1       cgd  */
     43   1.1       cgd 
     44   1.1       cgd #include "shell.h"
     45   1.1       cgd #include "nodes.h"
     46   1.1       cgd #include "memalloc.h"
     47   1.1       cgd #include "machdep.h"
     48   1.1       cgd #include "mystring.h"
     49   1.1       cgd 
     50   1.1       cgd 
     51  1.14       kre /* used to accumulate sizes of nodes */
     52  1.14       kre struct nodesize {
     53  1.14       kre 	int bsize;		/* size of structures in function */
     54  1.14       kre 	int ssize;		/* size of strings in node */
     55  1.14       kre };
     56  1.14       kre 
     57  1.14       kre /* provides resources for node copies */
     58  1.14       kre struct nodecopystate {
     59  1.14       kre 	pointer block;		/* block to allocate function from */
     60  1.14       kre 	char *string;		/* block to allocate strings from */
     61  1.14       kre };
     62  1.14       kre 
     63   1.1       cgd 
     64   1.1       cgd %SIZES
     65   1.1       cgd 
     66   1.1       cgd 
     67   1.1       cgd 
     68  1.14       kre STATIC void calcsize(union node *, struct nodesize *);
     69  1.14       kre STATIC void sizenodelist(struct nodelist *, struct nodesize *);
     70  1.14       kre STATIC union node *copynode(union node *, struct nodecopystate *);
     71  1.14       kre STATIC struct nodelist *copynodelist(struct nodelist *, struct nodecopystate *);
     72  1.14       kre STATIC char *nodesavestr(char *, struct nodecopystate *);
     73  1.14       kre 
     74  1.14       kre struct funcdef {
     75  1.14       kre 	unsigned int refcount;
     76  1.14       kre 	union node n;		/* must be last */
     77  1.14       kre };
     78   1.1       cgd 
     79   1.1       cgd 
     80   1.1       cgd /*
     81   1.1       cgd  * Make a copy of a parse tree.
     82   1.1       cgd  */
     83   1.1       cgd 
     84  1.14       kre struct funcdef *
     85  1.13      matt copyfunc(union node *n)
     86   1.7  christos {
     87  1.14       kre 	struct nodesize sz;
     88  1.14       kre 	struct nodecopystate st;
     89  1.14       kre 	struct funcdef *fn;
     90  1.14       kre 
     91   1.7  christos 	if (n == NULL)
     92   1.7  christos 		return NULL;
     93  1.14       kre 	sz.bsize = offsetof(struct funcdef, n);
     94  1.14       kre 	sz.ssize = 0;
     95  1.14       kre 	calcsize(n, &sz);
     96  1.14       kre 	fn = ckmalloc(sz.bsize + sz.ssize);
     97  1.14       kre 	fn->refcount = 1;
     98  1.14       kre 	st.block = (char *)fn + offsetof(struct funcdef, n);
     99  1.14       kre 	st.string = (char *)fn + sz.bsize;
    100  1.14       kre 	copynode(n, &st);
    101  1.14       kre 	return fn;
    102   1.1       cgd }
    103   1.1       cgd 
    104  1.14       kre union node *
    105  1.14       kre getfuncnode(struct funcdef *fn)
    106  1.14       kre {
    107  1.14       kre 	if (fn == NULL)
    108  1.14       kre 		return NULL;
    109  1.14       kre 	return &fn->n;
    110  1.14       kre }
    111   1.1       cgd 
    112   1.1       cgd 
    113   1.1       cgd STATIC void
    114  1.14       kre calcsize(union node *n, struct nodesize *res)
    115   1.7  christos {
    116   1.7  christos 	%CALCSIZE
    117   1.1       cgd }
    118   1.1       cgd 
    119   1.1       cgd 
    120   1.1       cgd 
    121   1.1       cgd STATIC void
    122  1.14       kre sizenodelist(struct nodelist *lp, struct nodesize *res)
    123   1.7  christos {
    124   1.7  christos 	while (lp) {
    125  1.14       kre 		res->bsize += SHELL_ALIGN(sizeof(struct nodelist));
    126  1.14       kre 		calcsize(lp->n, res);
    127   1.7  christos 		lp = lp->next;
    128   1.7  christos 	}
    129   1.1       cgd }
    130   1.1       cgd 
    131   1.1       cgd 
    132   1.1       cgd 
    133   1.1       cgd STATIC union node *
    134  1.14       kre copynode(union node *n, struct nodecopystate *st)
    135   1.7  christos {
    136   1.7  christos 	union node *new;
    137   1.1       cgd 
    138   1.7  christos 	%COPY
    139   1.7  christos 	return new;
    140   1.1       cgd }
    141   1.1       cgd 
    142   1.1       cgd 
    143   1.1       cgd STATIC struct nodelist *
    144  1.14       kre copynodelist(struct nodelist *lp, struct nodecopystate *st)
    145   1.7  christos {
    146   1.7  christos 	struct nodelist *start;
    147   1.7  christos 	struct nodelist **lpp;
    148   1.7  christos 
    149   1.7  christos 	lpp = &start;
    150   1.7  christos 	while (lp) {
    151  1.14       kre 		*lpp = st->block;
    152  1.14       kre 		st->block = (char *)st->block +
    153   1.9  christos 		    SHELL_ALIGN(sizeof(struct nodelist));
    154  1.14       kre 		(*lpp)->n = copynode(lp->n, st);
    155   1.7  christos 		lp = lp->next;
    156   1.7  christos 		lpp = &(*lpp)->next;
    157   1.7  christos 	}
    158   1.7  christos 	*lpp = NULL;
    159   1.7  christos 	return start;
    160   1.1       cgd }
    161   1.1       cgd 
    162   1.1       cgd 
    163   1.1       cgd 
    164   1.1       cgd STATIC char *
    165  1.14       kre nodesavestr(char *s, struct nodecopystate *st)
    166   1.7  christos {
    167   1.7  christos 	register char *p = s;
    168  1.14       kre 	register char *q = st->string;
    169  1.14       kre 	char   *rtn = st->string;
    170   1.7  christos 
    171  1.12       dsl 	while ((*q++ = *p++) != 0)
    172   1.7  christos 		continue;
    173  1.14       kre 	st->string = q;
    174   1.7  christos 	return rtn;
    175   1.1       cgd }
    176   1.1       cgd 
    177   1.1       cgd 
    178   1.1       cgd 
    179   1.1       cgd /*
    180  1.14       kre  * Handle making a reference to a function, and releasing it.
    181  1.14       kre  * Free the func code when there are no remaining references.
    182   1.1       cgd  */
    183   1.1       cgd 
    184   1.1       cgd void
    185  1.14       kre reffunc(struct funcdef *fn)
    186  1.14       kre {
    187  1.14       kre 	if (fn != NULL)
    188  1.14       kre 		fn->refcount++;
    189  1.14       kre }
    190  1.14       kre 
    191  1.14       kre void
    192  1.14       kre unreffunc(struct funcdef *fn)
    193  1.14       kre {
    194  1.14       kre 	if (fn != NULL) {
    195  1.14       kre 		if (--fn->refcount > 0)
    196  1.14       kre 			return;
    197  1.14       kre 		ckfree(fn);
    198  1.14       kre 	}
    199  1.14       kre }
    200  1.14       kre 
    201  1.14       kre /*
    202  1.14       kre  * this is used when we need to free the func, regardless of refcount
    203  1.14       kre  * which only happens when re-initing the shell for a SHELLPROC
    204  1.14       kre  */
    205  1.14       kre void
    206  1.14       kre freefunc(struct funcdef *fn)
    207   1.7  christos {
    208  1.14       kre 	if (fn != NULL)
    209  1.14       kre 		ckfree(fn);
    210   1.1       cgd }
    211