/* Copyright (c) 1997-2006			 -*- 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.
*/

#ifndef _POLYMAKE_XS_UTILS_H
#define _POLYMAKE_XS_UTILS_H "$Project: polymake $$Id: Ext.h,v 1.7 2006/02/06 15:46:41 gawrilow Exp $"

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#if !defined(TOPm1s) || !defined(PERL_MAGIC_ext) || !defined(OP_DESC)
#define not_PERL_5_8
# ifndef TOPm1s
# define TOPm1s (*(sp-1))
# endif
# ifndef PERL_MAGIC_ext
# define PERL_MAGIC_ext '~'
# endif
# ifndef OP_DESC
# define OP_DESC(o) PL_op_desc[(o)->op_type]
# endif
#endif

#ifdef PERL_IMPLICIT_CONTEXT
#ifdef USE_5005THREADS
#define aTHXtype struct perl_thread*
#else
#define aTHXtype PerlInterpreter*
#endif
extern aTHXtype aTHXvar;
#endif

static inline
I32 min (I32 a, I32 b) { return a<b ? a : b; }

static inline
I32 max (I32 a, I32 b) { return a>b ? a : b; }

static inline
void write_protect_on(SV *x)
{
   if (x != &PL_sv_undef) SvREADONLY_on(x);
}

static inline
void write_protect_off(SV *x)
{
   if (x != &PL_sv_undef) SvREADONLY_off(x);
}

void dump_me(SV *x);

static inline
SV **get_cx_curpad(pTHX_ PERL_CONTEXT *cx, PERL_CONTEXT *cx_bottom)
{
   CV *cv;
   I32 d;
   while (--cx>=cx_bottom) {
      switch (CxTYPE(cx)) {
      case CXt_SUB:
	 cv=cx->blk_sub.cv;
	 d=cx->blk_sub.olddepth;
	 goto FOUND;
      case CXt_EVAL:
	 if (!CxTRYBLOCK(cx)) {
	    cv=PL_compcv;
	    d=0;
	    goto FOUND;
	 }
      }
   }
   cv=PL_main_cv;
   d=0;
 FOUND:
   return (SV**)AvARRAY(((AV**)AvARRAY(CvPADLIST(cv)))[d+1]);
}

/* public export from Poly */
OP* select_method_helper_op(pTHX);

/* public export from namespaces */
SV* try_namespace_lookup(pTHX_ HV *stash, SV *name, I32 type);
HV* namespace_lookup_class(pTHX_ HV *stash, const char *class_name, STRLEN class_namelen);

#ifdef not_PERL_5_8
OP* fix_pp_dofile(pTHX);
#define std_pp_dofile fix_pp_dofile
#else
#define std_pp_dofile Perl_pp_dofile
#endif

extern CV *avoid_db_sub;

#endif /* _POLYMAKE_XS_UTILS_H */
