/* Copyright (c) 1997-2004			 -*- C -*-
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.de

   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 the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
*/

#ident "$Project: polymake $$Id: Shell.xs,v 1.1 2004/11/10 10:53:58 gawrilow Exp $"

#include "Ext.h"

MODULE = Poly::Shell		PACKAGE = Poly::Shell

PROTOTYPES: DISABLE

void
return_to_var()
PPCODE:
{
   PERL_CONTEXT *cx_bottom=cxstack, *cx=cx_bottom+cxstack_ix;
   OP *next_op;
   GV *gv;

   XPUSHs(&PL_sv_undef);	/* default answer */
   while (cx >= cx_bottom) {
      if (CxTYPE(cx) == CXt_SUB) {
	 if (cx->blk_gimme != G_SCALAR)
	    break;
	 next_op=PL_retstack[cx->blk_oldretsp-1];
	 if (next_op->op_type != OP_LEAVESUB) {
	    if (next_op->op_type == OP_GVSV  &&  next_op->op_next->op_type == OP_SASSIGN) {
#ifdef USE_ITHREADS
	       SV **saved_curpad=PL_curpad;
	       PL_curpad=get_cx_curpad(aTHX_ cx, cx_bottom);
#endif
	       gv=cGVOPx_gv(next_op);
#ifdef USE_ITHREADS
	       PL_curpad=saved_curpad;
#endif
	       TOPs=sv_2mortal(newSVpvn(GvNAME(gv),GvNAMELEN(gv)));
	    }
	    break;
	 }
      }
      --cx;
   }
}

void
get_chained(...)
PPCODE:
{
   PERL_CONTEXT *cx_bottom=cxstack, *cx=cx_bottom+cxstack_ix;
   while (cx >= cx_bottom) {
      if (CxTYPE(cx) == CXt_SUB) {
	 OP *o=PL_retstack[cx->blk_oldretsp-1];
	 cx->blk_gimme=G_ARRAY;
	 if (o->op_type != OP_LEAVESUB) {
	    I32 skip=FALSE;
#ifdef USE_ITHREADS
	    SV **saved_curpad=0;
#endif
	    while (o->op_type == OP_CONST && o->op_next->op_type == OP_CONCAT) {
#ifdef USE_ITHREADS
	       if (!skip) {
		  saved_curpad=PL_curpad;
		  PL_curpad=get_cx_curpad(aTHX_ cx, cx_bottom);
	       }
#endif
	       XPUSHs(cSVOPo_sv);
	       skip=TRUE;
	       o=o->op_next->op_next;
	    }
	    if (skip) {
	       PL_retstack[cx->blk_oldretsp-1]=o;
#ifdef USE_ITHREADS
	       PL_curpad=saved_curpad;
#endif
	    }
	    break;
	 }
      }
      --cx;
   }
}
items=0;


BOOT:
if (PL_DBgv) {
   CvNODEBUG_on(get_cv("Poly::Shell::return_to_var", FALSE));
   CvNODEBUG_on(get_cv("Poly::Shell::get_chained", FALSE));
}
