Logo Search packages:      
Sourcecode: yorick-yeti version File versions

yeti_new.c

/*
 * yeti_new.c --
 *
 *    Various built-in functions using the ney Yorick API defined in
 *    'yapi.h'.
 *
 *-----------------------------------------------------------------------------
 *
 *      Copyright (C) 2005-2006, Eric Thiébaut.
 *
 *    This file is part of Yeti.
 *
 *    Yeti is  free software;  you can redistribute  it and/or  modify it
 *    under  the terms of  the GNU  General Public  License version  2 as
 *    published by the Free Software Foundation.
 *
 *    Yeti 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.
 *
 *    You should have  received a copy of the  GNU General Public License
 *    along with  Yeti (file "COPYING"  in the top source  directory); if
 *    not, write to  the Free Software Foundation, Inc.,  51 Franklin St,
 *    Fifth Floor, Boston, MA 02110-1301 USA
 *
 *-----------------------------------------------------------------------------
 *
 * History:
 *    $Id: yeti_new.c,v 1.1 2006/07/19 14:52:26 eric Exp $
 *    $Log: yeti_new.c,v $
 *    Revision 1.1  2006/07/19 14:52:26  eric
 *    Initial revision
 *
 */

#ifndef _YETI_NEW_C
#define _YETI_NEW_C 1

#include <string.h>
#include <stdarg.h>
#include <stdio.h>

#include <unistd.h>

#include <pstdlib.h>
#include "yapi.h"


#define type_t     unsigned char
#define CHECK_DIMS check_dims_c
#include __FILE__

#define type_t     short
#define CHECK_DIMS check_dims_s
#include __FILE__

#define type_t     int
#define CHECK_DIMS check_dims_i
#include __FILE__

#define type_t     long
#define CHECK_DIMS check_dims_l
#include __FILE__


#if 0
void Y_tmpfile(int argc)
{
  const char *tail = "XXXXXX";
  ystring_t src, dst, *arr;
  long len, size;
  int pad, fd;

  if (argc != 1) y_error("tmpfile takes exaclty one argument");
  src = ygets_q(0);
  len = (src && src[0] ? strlen(src) : 0);
  if (len < 6 || strcmp(src + (len - 6), tail)) {
    pad = 1;
    size = len + 7;
  } else {
    pad = 0;
    size = len + 1;
  }
  arr = ypush_q(0);
  dst = p_malloc(size);
  dst[size - 1] = '\0'; /* mark end of string */
  arr[0] = dst; /* then store string pointer */
  if (len > 0) memcpy(dst, src, len);
  if (pad) memcpy(dst + len, tail, 6);
  fprintf(stderr, "template=\"%s\"\n", dst);
  fd = mkstemp(dst);
  if (fd < 0) {
    y_error("tmpfile failed to create a unique temporary file");
  } else {
    close(fd);
  }
}
#endif

#if 0
void Y_is_dimlist(int argc)
{
}
#endif

/* n  or [l, n1, n2, .., nl] */
void Y_make_dimlist(int argc)
{
  long *dimlist, dims[Y_DIMSIZE], ref, ndims, ndims_first, j, n;
  int iarg;

  if (argc < 1) y_error("make_dimlist takes at least one argument");
  if (yarg_subroutine()) {
    ref = yget_ref(argc - 1);
    if (ref < 0L) y_error("expecting a simple reference for first argument");
  } else {
    ref = -1L;
  }

  /* First pass: count total number of dimensions. */
  ndims_first = -1L;
  ndims = 0L;
  for (iarg = argc - 1 ; iarg >= 0 ; --iarg) {
    switch (yarg_typeid(iarg)) {
    case Y_CHAR:
      ndims += check_dims_c(ygeta_c(iarg, NULL, dims), dims);
      break;
    case Y_SHORT:
      ndims += check_dims_s(ygeta_s(iarg, NULL, dims), dims);
      break;
    case Y_INT:
      ndims += check_dims_i(ygeta_i(iarg, NULL, dims), dims);
      break;
    case Y_LONG:
      ndims += check_dims_l(ygeta_l(iarg, NULL, dims), dims);
      if (iarg == argc - 1 && ref >= 0L && dims[0] == 1L) {
      ndims_first = ndims;
      }
      break;
    case Y_VOID:
      break;
    default:
       y_error("unexpected data type in dimension list");
    }
  }

  if (ndims_first == ndims) {
    /* nothing to do */
    return;
  }

  /* Second pass: build up new dimension list. */
  dims[0] = 1;
  dims[1] = ndims + 1;
  dimlist = ypush_l(dims);
  *dimlist = ndims;
  for (iarg = argc ; iarg > 0 ; --iarg) {
#define GET_DIMS(type_t, x)                     \
      {                                         \
      type_t *ptr = ygeta_##x(iarg, &n, NULL);  \
      if (n > 1L) {                             \
        for (j=1L ; j<n ; ++j) {                \
          *++dimlist = ptr[j];                  \
        }                                 \
      } else {                            \
        *++dimlist = ptr[0];                    \
      }                                   \
      }                                         \
      break
    switch (yarg_typeid(iarg)) {
    case Y_CHAR:  GET_DIMS(unsigned char, c);
    case Y_SHORT: GET_DIMS(short,         s);
    case Y_INT:   GET_DIMS(int,           i);
    case Y_LONG:  GET_DIMS(long,          l);
    }
#undef GET_DIMS
  }
  
  if (ref >= 0L) {
    /* replace reference by topmost stack element */
    yput_global(ref, 0);
  }
}

#else /* _YETI_NEW_C defined */

#ifdef CHECK_DIMS
static long CHECK_DIMS(const type_t value[], const long dims[])
{
  long j, n;
  
  n = value[0];
  if (! dims[0] && n > 0L) return 1L;
  if (dims[0] == 1L && dims[1] == n + 1L) {
    for (j=1L ; j<=n ; ++j) {
      if (value[j] <= 0) {
      goto bad_dimlist;
      }
    }
    return n;
  }
 bad_dimlist:
  y_error("bad dimension list");
  return -1L; /* avoid compiler warnings */
}
#endif /* CHECK_DIMS */

#undef type_t
#undef CHECK_DIMS
#endif /* _YETI_NEW_C defined */

Generated by  Doxygen 1.6.0   Back to index