LTP GCOV extension - code coverage report
Current view: directory - fcode-utils/toke - stack.c
Test: toke.info
Date: 2006-08-18 Instrumented lines: 59
Code covered: 88.1 % Executed lines: 52

       1                 : /*
       2                 :  *                     OpenBIOS - free your system! 
       3                 :  *                         ( FCode tokenizer )
       4                 :  *                          
       5                 :  *  stack.c - data and return stack handling for fcode tokenizer.
       6                 :  *  
       7                 :  *  This program is part of a free implementation of the IEEE 1275-1994 
       8                 :  *  Standard for Boot (Initialization Configuration) Firmware.
       9                 :  *
      10                 :  *  Copyright (C) 2001-2005 by Stefan Reinauer <stepan@openbios.org>
      11                 :  *
      12                 :  *  This program is free software; you can redistribute it and/or modify
      13                 :  *  it under the terms of the GNU General Public License as published by
      14                 :  *  the Free Software Foundation; version 2 of the License.
      15                 :  *
      16                 :  *  This program is distributed in the hope that it will be useful,
      17                 :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :  *  GNU General Public License for more details.
      20                 :  *
      21                 :  *  You should have received a copy of the GNU General Public License
      22                 :  *  along with this program; if not, write to the Free Software
      23                 :  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
      24                 :  *
      25                 :  */
      26                 : 
      27                 : /* **************************************************************************
      28                 :  *         Modifications made in 2005 by IBM Corporation
      29                 :  *      (C) Copyright 2005 IBM Corporation.  All Rights Reserved.
      30                 :  *      Modifications Author:  David L. Paktor    dlpaktor@us.ibm.com
      31                 :  **************************************************************************** */
      32                 : 
      33                 : #include <stdlib.h>
      34                 : #include <stdio.h>
      35                 : #include <string.h>
      36                 : 
      37                 : #include "stack.h"
      38                 : #include "scanner.h"
      39                 : #include "errhandler.h"
      40                 : 
      41                 : /* **************************************************************************
      42                 :  *
      43                 :  *          Global Variables Imported
      44                 :  *              statbuf          The word just read from the input stream
      45                 :  *
      46                 :  **************************************************************************** */
      47                 : 
      48                 : 
      49                 : /* **************************************************************************
      50                 :  *
      51                 :  *          Global Variables Exported
      52                 :  *              dstack         Pointer to current item on top of Data Stack
      53                 :  *
      54                 :  **************************************************************************** */
      55                 : 
      56                 : long *dstack;
      57                 : 
      58                 : /* **************************************************************************
      59                 :  *
      60                 :  *      Local/Static Pointers  .....      to  ...         -> Points to ...
      61                 :  *          startdstack         Start of data-stack area  -> last possible item
      62                 :  *          enddstack           End of data-stack area    -> past first item
      63                 :  *
      64                 :  *************************************************************************** */
      65                 : 
      66                 : static long *startdstack;
      67                 : static long *enddstack;
      68                 : 
      69                 : void clear_stack(void)
      70             170 : {
      71             170 :     dstack = enddstack;
      72             170 : }
      73                 : 
      74                 : /* internal stack functions */
      75                 : 
      76                 : void init_stack(void)
      77             154 : {
      78             154 :         startdstack = safe_malloc(MAX_ELEMENTS*sizeof(long), "initting stack");
      79             154 :         enddstack = startdstack + MAX_ELEMENTS;
      80             154 :         dstack=enddstack;
      81             154 : }
      82                 : 
      83                 : /*  Input Param:  stat   TRUE = Underflow, FALSE = Overflow   */
      84                 : static void stackerror(bool stat)
      85              14 : {
      86                 :     /*
      87                 :      *   Because all of our stack operations are protected and
      88                 :      *       we have no risk of the  dstack  pointer going into
      89                 :      *       invalid territory, this error needs not be  FATAL.
      90                 :      */
      91              14 :     tokenization_error ( TKERROR , "stack %sflow at or near  %s \n",
      92                 :          (stat)?"under":"over" , statbuf );
      93              14 : }
      94                 : 
      95                 : /*
      96                 :  *  Return TRUE if the stack depth is equal to or greater than
      97                 :  *      the supplied minimum requirement.  If not, print an error.
      98                 :  */
      99                 : bool min_stack_depth(int mindep)
     100             641 : {
     101             641 :     bool retval = TRUE ;
     102                 :     long *stack_result;
     103                 : 
     104             641 :     stack_result = dstack + mindep;
     105                 :     /*
     106                 :      *  The above appears counter-intuitive.  However, C compensates
     107                 :      *      for the size of the object of a pointer when it handles
     108                 :      *      address arithmetic.  A more explicit expression that would
     109                 :      *      yield the same result, might look something like this:
     110                 :      *
     111                 :      *        (long *)((int)dstack + (mindep * sizeof(long)))
     112                 :      *
     113                 :      *  I doubt that that form would yield tighter code, or otherwise
     114                 :      *      represent any material advantage...
     115                 :      */
     116                 : 
     117             641 :     if ( stack_result > enddstack )
     118                 :     {
     119              14 :         retval = FALSE;
     120              14 :         stackerror(TRUE);
     121                 :     }
     122                 : 
     123             641 :     return ( retval );
     124                 : }
     125                 : 
     126                 : /*
     127                 :  *  Return TRUE if the stack has room for the supplied # of items
     128                 :  */
     129                 : static bool room_on_stack_for(int newdep)
     130             637 : {
     131             637 :     bool retval = TRUE ;
     132                 :     long *stack_result;
     133                 : 
     134             637 :     stack_result = dstack - newdep;
     135                 :     /*  See above note about "counter-intuitive" pointer address arithmetic  */
     136                 : 
     137             637 :     if ( stack_result < startdstack )
     138                 :     {
     139               0 :         retval = FALSE;
     140               0 :         stackerror(FALSE);
     141                 :     }
     142                 : 
     143             637 :     return ( retval );
     144                 : }
     145                 : 
     146                 : void dpush(long data)
     147             637 : {
     148                 : #ifdef DEBUG_DSTACK
     149                 :         printf("dpush: sp=%p, data=0x%lx, ", dstack, data);
     150                 : #endif
     151             637 :         if ( room_on_stack_for(1) )
     152                 :         {
     153             637 :             --dstack;
     154             637 :             *(dstack)=data;
     155                 :         }
     156             637 : }
     157                 : 
     158                 : long dpop(void)
     159             637 : {
     160             637 :         long val = 0;
     161                 : #ifdef DEBUG_DSTACK
     162                 :         printf("dpop: sp=%p, data=0x%lx, ",dstack, *dstack);
     163                 : #endif
     164             637 :         if ( min_stack_depth(1) )
     165                 :         {
     166             624 :             val=*(dstack);
     167             624 :             dstack++;
     168                 :         }
     169             637 :         return val;
     170                 : }
     171                 : 
     172                 : long dget(void)
     173               0 : {
     174               0 :         long val = 0;
     175               0 :         if ( min_stack_depth(1) )
     176                 :         {
     177               0 :             val = *(dstack);
     178                 :         }
     179               0 :         return val;
     180                 : }
     181                 : 
     182                 : long stackdepth(void)
     183             170 : {
     184                 :     long depth;
     185                 : 
     186             170 :     depth = enddstack - dstack;
     187                 :     /*
     188                 :      *  Again, C's address arithmetic compensation comes into play.
     189                 :      *      See the note at  min_stack_depth()
     190                 :      *
     191                 :      *  A more explicit equivalent expression might look like this:
     192                 :      *
     193                 :      *        (((long int)enddstack - (long int)dstack) / sizeof(long))
     194                 :      *
     195                 :      *  I doubt any material advantage with that one either...
     196                 :      */
     197                 : 
     198             170 :     return (depth);
     199                 : }
     200                 : 
     201                 : void swap(void)
     202               3 : {
     203                 :     long nos_temp;    /*  Next-On-Stack temp  */
     204               3 :     if ( min_stack_depth(2) )
     205                 :     {
     206               2 :         nos_temp = dstack[1];
     207               2 :         dstack[1]= dstack[0];
     208               2 :         dstack[0]= nos_temp;
     209                 :     }
     210               3 : }
     211                 : 
     212                 : void two_swap(void)
     213               1 : {
     214                 :     long two_deep, three_deep;
     215               1 :     if ( min_stack_depth(4) )
     216                 :     {
     217               1 :         two_deep   = dstack[2];
     218               1 :         three_deep = dstack[3];
     219               1 :         dstack[2]  = dstack[0];
     220               1 :         dstack[3]  = dstack[1];
     221               1 :         dstack[1]  = three_deep;
     222               1 :         dstack[0]  = two_deep;
     223                 :     }
     224               1 : }
     225                 : 
     226                 : 

Generated by: LTP GCOV extension version 1.5