Description: wrap 64-bit long hid_t into Yorick's "long" type
 HDF5 has changed hid_t to now be always 64bit. There is no
 64-bit-long type in Yorick on 32-bit architectures. On these
 architectures, we keep a list of open ids and index them with the
 32-bit long "long" type.
Author: Thibaut Paumard
Origin: vendor
Bug: https://github.com/frigaut/yorick-hdf5/issues/1
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=842817
Last-Update: 2016-11-03
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/hdf5.c
+++ b/hdf5.c
@@ -34,8 +34,107 @@
 #include <stdlib.h> /* For EXIT_FAILURE, EXIT_SUCCESS */
 #include "hdf5.h"
 #include "ydata.h"
+#include "yapi.h"
 #include "pstdlib.h"
 
+/* Make a new data type for hid_t */
+// Y_WRAP_HID_T should be defined whenever sizeof(long) < sizeof(hid_t).
+// User may force wrapping.
+#ifndef Y_WRAP_HID_T
+# if H5_SIZEOF_LONG < H5_SIZEOF_HID_T
+#  define Y_WRAP_HID_T
+# endif
+#endif
+
+#ifndef Y_WRAP_HID_T
+// Y_WRAP_HID_T is not defined: hid_t can be represented immediately
+// as either int or long.
+# if H5_SIZEOF_HID_T <= H5_SIZEOF_INT
+#  define ypush_hid_t ypush_int
+#  define ygets_hid_t ygets_i
+# else
+#  define ypush_hid_t ypush_long
+#  define ygets_hid_t ygets_l
+# endif
+# define yfree_hid_t(hid) do {} while (0)
+
+#else
+// Y_WRAP_HID_T is defined: wrap hid_t into long. We will maintain a
+// list of hid_t values, the interpreter will only see long integer
+// references to this list.
+
+#define Y_H5_DEFAULT_SIZE 1024
+static struct {
+  hid_t * ids;
+  size_t n_allocated;
+  long last;
+} y_hids = {
+  .ids = 0,
+  .n_allocated = 0,
+  .last = -1,
+} ;
+
+void ypush_hid_t(hid_t hid) {
+  long yid=0;
+  if (hid <0) yid=-1;
+  else if (hid >0) {
+    if (y_hids.n_allocated == 0) {
+      y_hids.ids=malloc(Y_H5_DEFAULT_SIZE*sizeof(hid_t));
+      if (!(y_hids.ids)) y_error("Failed to allocate list of hids");
+      y_hids.n_allocated = Y_H5_DEFAULT_SIZE;
+    }
+    long cur;
+    long first_free=-1;
+    for (cur=0; cur<=y_hids.last; ++cur) {
+      if (y_hids.ids[cur] == hid) {
+	yid = cur+1; // because we map hid=0 to yid=0
+	break;
+      }
+      if (y_hids.ids[cur]==-1 && first_free==-1) first_free=cur;
+    }
+    if (yid==0) { // did not find matching id
+      if (first_free != -1) cur=first_free;
+      yid=cur+1;
+      if (yid<0) { // long int overflow
+	y_error("Pushed to many hids, please close some");
+      }
+      if (yid>y_hids.n_allocated) { // need to grow y_hids.ids
+	size_t n_allocated=2*y_hids.n_allocated;
+	hid_t * tmp=realloc(y_hids.ids, n_allocated*sizeof(hid_t));
+	if (!tmp) y_error("Failed to grow list of hids");
+	y_hids.ids=tmp;
+	y_hids.n_allocated=n_allocated;
+      }
+      y_hids.ids[cur]=hid;
+      if (cur > y_hids.last) y_hids.last=cur;
+    }
+  }
+  ypush_long(yid);
+}
+
+hid_t ygets_hid_t(int iarg) {
+  // receive hid_t from Yorick.
+  long yid=ygets_l(iarg);
+  if (yid<=0) return yid;
+  long cur=yid-1;
+  if (cur>y_hids.last) y_error("No such id. Was it closed already?");
+  return y_hids.ids[cur];
+}
+
+void yfree_hid_t(hid_t hid) {
+  long cur, i;
+  for (cur=0; cur<=y_hids.last; ++cur) {
+    if (y_hids.ids[cur] == hid) {
+      y_hids.ids[cur]=-1;
+      break;
+    }
+  }
+  while (y_hids.last>=0 && y_hids.ids[y_hids.last]==-1) --y_hids.last;
+}
+#endif
+
+/* Done wrapping 64-bit hids into 32-bit yids */
+
 void Y__H5Eon()   { H5Eset_auto((H5E_auto_t)H5Eprint,stderr); }
 void Y__H5Eoff()  { H5Eset_auto(NULL,NULL); }
 void Y__H5close() { H5close(); }
@@ -59,34 +158,35 @@
   long mode = YGetInteger(sp-nArgs+2);
   long create_id = YGetInteger(sp-nArgs+3);
   long access_id = YGetInteger(sp-nArgs+4);
-  int status;
-  status=H5Fcreate(filename, (uint) mode, (hid_t) create_id, (hid_t) access_id);
-  PushIntValue(status);
+  hid_t id;
+  id=H5Fcreate(filename, (uint) mode, (hid_t) create_id, (hid_t) access_id);
+  ypush_hid_t(id);
 }
 
 void Y__H5Fopen(int nArgs)
 {
   char *filename = YGetString(sp-nArgs+1);
   long flags = YGetInteger(sp-nArgs+2);
-  long access_id = YGetInteger(sp-nArgs+3);
-  int status;
-  status=H5Fopen(filename, (uint) flags, (hid_t) access_id);
-  PushIntValue(status);
+  hid_t access_id = ygets_hid_t(nArgs-3);
+  hid_t id;
+  id=H5Fopen(filename, (uint) flags, (hid_t) access_id);
+  ypush_hid_t(id);
 }
 
 void Y__H5Fclose(int nArgs)
 {
-  long file_id = YGetInteger(sp-nArgs+1);
-  int status;
-  H5Fflush((hid_t) file_id, H5F_SCOPE_LOCAL);
-  status=H5Fclose((hid_t) file_id);
+  hid_t file_id = ygets_hid_t(nArgs-1);
+  herr_t status;
+  H5Fflush(file_id, H5F_SCOPE_LOCAL);
+  status=H5Fclose(file_id);
+  yfree_hid_t(file_id);
   PushIntValue(status);
 }
 
 
 void Y__H5Areads(int nArgs)
 {
-  long attid = YGetInteger(sp-nArgs+1);
+  hid_t attid = ygets_hid_t(nArgs-1);
   Dimension *strdims = 0;
   char **data=  YGet_Q(sp-nArgs+2,0,&strdims);
   long nelem = YGetInteger(sp-nArgs+3);
@@ -114,7 +214,7 @@
 
 void Y__H5Dreads(int nArgs)
 {
-  long did = YGetInteger(sp-nArgs+1);
+  hid_t did = ygets_hid_t(nArgs-1);
   Dimension *strdims = 0;
   char **data=  YGet_Q(sp-nArgs+2,0,&strdims);
   long nelem = YGetInteger(sp-nArgs+3);
@@ -140,52 +240,54 @@
 
 void Y__H5Gget_linkval(int nArgs)
 {
-  long loc_id = YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   char *gname = YGetString(sp-nArgs+2);
   long size = YGetInteger(sp-nArgs+3);
   char *value = YGetString(sp-nArgs+4);
 
-  PushIntValue((long)H5Gget_linkval((hid_t) loc_id, gname, (size_t)size, value));
+  PushIntValue((long)H5Gget_linkval(loc_id, gname, (size_t)size, value));
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 
 void Y__H5Gopen(nArgs)
 {
-  long loc_id = YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   char *gname = YGetString(sp-nArgs+2);
 
-  PushIntValue((long)H5Gopen((hid_t)loc_id, gname));
+  ypush_hid_t(H5Gopen(loc_id, gname));
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 
 void Y__H5Gclose(nArgs)
 {
-  long gid = YGetInteger(sp-nArgs+1);
+  hid_t gid = ygets_hid_t(nArgs-1);
 
-  PushIntValue((long)H5Gclose((hid_t)gid));
+  PushIntValue((long)H5Gclose(gid));
+  yfree_hid_t(gid);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 
 void Y__H5Gcreate(nArgs)
 {
-  long loc_id = YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   char *gname = YGetString(sp-nArgs+2);
   long size_hint = YGetInteger(sp-nArgs+3);
+  hid_t result=H5Gcreate(loc_id, gname, (size_t)size_hint);
 
-  PushIntValue((long)H5Gcreate((hid_t)loc_id, gname, (size_t)size_hint));
+  ypush_hid_t(result);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 
 void Y__H5Gget_num_objs(nArgs)
 {
-  long gid = YGetInteger(sp-nArgs+1);
+  hid_t gid = ygets_hid_t(nArgs-1);
   hsize_t num_obj=0;
 
-  H5Gget_num_objs((hid_t)gid, &num_obj);
+  H5Gget_num_objs(gid, &num_obj);
   PushIntValue((long)num_obj);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
@@ -193,36 +295,36 @@
 
 void Y__H5Gget_objname_by_idx(int nArgs)
 {
-  long loc_id = YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   long idx    = YGetInteger(sp-nArgs+2);
   char *name  = YGetString(sp-nArgs+3);
   long size   = YGetInteger(sp-nArgs+4);
 
-  H5Gget_objname_by_idx((hid_t)loc_id, (hsize_t)idx,name,(size_t)size);
+  H5Gget_objname_by_idx(loc_id, (hsize_t)idx,name,(size_t)size);
   Drop(nArgs);
 }
 
 
 void Y__H5Gget_objtype_by_idx(int nArgs)
 {
-  long loc_id = YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   long idx    = YGetInteger(sp-nArgs+2);
 
-  PushIntValue((long)H5Gget_objtype_by_idx((hid_t)loc_id, (hsize_t)idx));
+  PushIntValue((long)H5Gget_objtype_by_idx(loc_id, (hsize_t)idx));
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 
 void Y__H5Gget_objtype_by_name(int nArgs)
 {
-  long loc_id = YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   char *name  = YGetString(sp-nArgs+2);
   Dimension *dims = 0;
   long *objnum = YGet_L(sp-nArgs+3,0, &dims);
 
   H5G_stat_t   statbuf;
   hbool_t      followlink=0;
-  H5Gget_objinfo((hid_t)loc_id,name,followlink,&statbuf);
+  H5Gget_objinfo(loc_id,name,followlink,&statbuf);
 
   objnum[0] = statbuf.objno[0];
   objnum[1] = statbuf.objno[1];
@@ -234,14 +336,14 @@
 
 void Y__H5Glink2(int nArgs)
 {
-  long curr_loc_id = YGetInteger(sp-nArgs+1);
+  hid_t curr_loc_id = ygets_hid_t(nArgs-1);
   char *curname    = YGetString(sp-nArgs+2);
   long link_type   = YGetInteger(sp-nArgs+3);
-  long new_loc_id  = YGetInteger(sp-nArgs+4);
+  hid_t new_loc_id  = ygets_hid_t(nArgs-4);
   char *newname    = YGetString(sp-nArgs+5);
 
-  PushIntValue((long)H5Glink2((hid_t)curr_loc_id, curname, 
-			      (H5G_link_t)link_type, (hid_t)new_loc_id, 
+  PushIntValue((long)H5Glink2(curr_loc_id, curname,
+			      (H5G_link_t)link_type, new_loc_id,
 			      newname));
   PopTo(sp-nArgs-1);
   Drop(nArgs);
@@ -249,29 +351,29 @@
 
 void Y__H5Gunlink(int nArgs)
 {
-  long loc_id = YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   char *name    = YGetString(sp-nArgs+2);
 
-  PushIntValue((long)H5Gunlink((hid_t)loc_id, name)); 
+  PushIntValue((long)H5Gunlink(loc_id, name));
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 
 void Y__H5Pcreate(int nArgs)
 {
-  long cls_id = YGetInteger(sp-nArgs+1);
+  hid_t cls_id = ygets_hid_t(nArgs-1);
 
-  PushIntValue((long)H5Pcreate((hid_t)cls_id)); 
+  ypush_hid_t(H5Pcreate(cls_id));
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 
 void Y__H5Pset_deflate(int nArgs)
 {
-  long plist = YGetInteger(sp-nArgs+1);
+  hid_t plist = ygets_hid_t(nArgs-1);
   long level = YGetInteger(sp-nArgs+2);
 
-  PushIntValue((long)H5Pset_deflate((hid_t)plist,(int)level)); 
+  PushIntValue((long)H5Pset_deflate(plist,(int)level));
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -282,7 +384,7 @@
 
 void Y__H5Pset_chunk(int nArgs)
 {
-  long plist=YGetInteger(sp-nArgs+1);
+  hid_t plist = ygets_hid_t(nArgs-1);
   long ndims=YGetInteger(sp-nArgs+2);
   Dimension *tmpdims = 0;
   long *dim=YGet_L(sp-nArgs+3,0,&tmpdims);
@@ -293,7 +395,7 @@
 
   for (i=0;i<ndims;i++) hdim[i]=(hsize_t)dim[i];
 
-  status=(long)H5Pset_chunk((hid_t)plist,(int)ndims, hdim);
+  status=(long)H5Pset_chunk(plist,(int)ndims, hdim);
 
   PushIntValue(status);
   PopTo(sp-nArgs-1);
@@ -303,18 +405,17 @@
 //hid_t H5Acreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t create_plist)
 void Y__H5Acreate(int nArgs)
 {
-  long loc_id=YGetInteger(sp-nArgs+1);
+  hid_t loc_id       = ygets_hid_t(nArgs-1);
   char *name=YGetString(sp-nArgs+2);
-  long type_id=YGetInteger(sp-nArgs+3);
-  long space_id=YGetInteger(sp-nArgs+4);
-  long create_plist=YGetInteger(sp-nArgs+5);
+  hid_t type_id      = ygets_hid_t(nArgs-3);
+  hid_t space_id     = ygets_hid_t(nArgs-4);
+  hid_t create_plist = ygets_hid_t(nArgs-5);
   
-  long status;
+  hid_t id;
 
-  status=(long)H5Acreate((hid_t)loc_id, name, (hid_t)type_id, 
-			 (hid_t)space_id,(hid_t)create_plist);
+  id=H5Acreate(loc_id, name, type_id, space_id,create_plist);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -323,7 +424,7 @@
 
 void Y__H5Adelete(int nArgs)
 {
-  long loc_id=YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   char *name=YGetString(sp-nArgs+2);
   
   long status;
@@ -340,7 +441,7 @@
 
 void Y__H5Aget_num_attrs(int nArgs)
 {
-  long loc_id=YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   
   long status;
 
@@ -355,13 +456,13 @@
 
 void Y__H5Aget_type(int nArgs)
 {
-  long attr_id=YGetInteger(sp-nArgs+1);
+  hid_t attr_id = ygets_hid_t(nArgs-1);
   
-  long status;
+  hid_t id;
 
-  status=(long)H5Aget_type((hid_t)attr_id);
+  id=H5Aget_type(attr_id);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -370,20 +471,20 @@
 
 void Y__H5Aget_space(int nArgs)
 {
-  long attr_id=YGetInteger(sp-nArgs+1);
+  hid_t attr_id = ygets_hid_t(nArgs-1);
   
-  long status;
+  hid_t id;
 
-  status=(long)H5Aget_space((hid_t)attr_id);
+  id=H5Aget_space(attr_id);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 
 void Y__H5Aget_name(int nArgs)
 {
-  long attr_id=YGetInteger(sp-nArgs+1);
+  hid_t attr_id = ygets_hid_t(nArgs-1);
   long buf_size=YGetInteger(sp-nArgs+2);
   char *buf=YGetString(sp-nArgs+3);
   
@@ -391,7 +492,7 @@
 
   status=(long)H5Aget_name((hid_t)attr_id, (size_t)buf_size, buf);
 
-  PushIntValue(status);
+  PushLongValue(status);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -400,14 +501,14 @@
 
 void Y__H5Aopen_idx(int nArgs)
 {
-  long loc_id=YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   long idx=YGetInteger(sp-nArgs+2);
   
-  long status;
+  hid_t id;
 
-  status=(long)H5Aopen_idx((hid_t)loc_id, (unsigned int)idx);
+  id=H5Aopen_idx(loc_id, (unsigned int)idx);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -416,14 +517,14 @@
 
 void Y__H5Aopen_name(int nArgs)
 {
-  long loc_id=YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   char *name=YGetString(sp-nArgs+2);
   
-  long status;
+  hid_t id;
 
-  status=(long)H5Aopen_name((hid_t)loc_id, name);
+  id=H5Aopen_name(loc_id, name);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -432,12 +533,12 @@
 
 void Y__H5Aread(int nArgs)
 {
-  long attr_id=YGetInteger(sp-nArgs+1);
-  long mem_type_id=YGetInteger(sp-nArgs+2);
+  hid_t attr_id = ygets_hid_t(nArgs-1);
+  hid_t mem_type_id = ygets_hid_t(nArgs-2);
   
   long status;
 
-  status=(long)H5Aread((hid_t)attr_id, (hid_t)mem_type_id, yarg_sp(0));
+  status=(long)H5Aread(attr_id, mem_type_id, yarg_sp(0));
 
   PushIntValue(status);
   PopTo(sp-nArgs-1);
@@ -446,12 +547,12 @@
 
 void Y__H5Awrite(int nArgs)
 {
-  long attr_id=YGetInteger(sp-nArgs+1);
-  long mem_type_id=YGetInteger(sp-nArgs+2);
+  hid_t attr_id = ygets_hid_t(nArgs-1);
+  hid_t mem_type_id = ygets_hid_t(nArgs-2);
 
   long status;
 
-  status=(long)H5Awrite((hid_t)attr_id, (hid_t)mem_type_id, yarg_sp(0));
+  status=(long)H5Awrite(attr_id, mem_type_id, yarg_sp(0));
 
   PushIntValue(status);
   PopTo(sp-nArgs-1);
@@ -462,11 +563,12 @@
 
 void Y__H5Aclose(int nArgs)
 {
-  long attr_id=YGetInteger(sp-nArgs+1);
+  hid_t attr_id = ygets_hid_t(nArgs-1);
   
   long status;
 
   status=(long)H5Aclose((hid_t)attr_id);
+  yfree_hid_t(attr_id);
 
   PushIntValue(status);
   PopTo(sp-nArgs-1);
@@ -477,11 +579,12 @@
 
 void Y__H5Dclose(int nArgs)
 {
-  long dataset_id=YGetInteger(sp-nArgs+1);
+  hid_t dataset_id = ygets_hid_t(nArgs-1);
   
   long status;
 
   status=(long)H5Dclose((hid_t)dataset_id);
+  yfree_hid_t(dataset_id);
 
   PushIntValue(status);
   PopTo(sp-nArgs-1);
@@ -493,18 +596,17 @@
 
 void Y__H5Dcreate(int nArgs)
 {
-  long loc_id=YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   char *name=YGetString(sp-nArgs+2);
-  long type_id=YGetInteger(sp-nArgs+3);
-  long space_id=YGetInteger(sp-nArgs+4);
-  long create_plist_id=YGetInteger(sp-nArgs+5);
+  hid_t type_id = ygets_hid_t(nArgs-3);
+  hid_t space_id = ygets_hid_t(nArgs-4);
+  hid_t create_plist_id = ygets_hid_t(nArgs-5);
   
-  long status;
+  hid_t id;
 
-  status=(long)H5Dcreate((hid_t)loc_id, name, (hid_t)type_id, 
-			 (hid_t)space_id,(hid_t)create_plist_id);
+  id=H5Dcreate(loc_id, name, type_id, space_id, create_plist_id);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -513,14 +615,14 @@
 
 void Y__H5Dopen(int nArgs)
 {
-  long loc_id=YGetInteger(sp-nArgs+1);
+  hid_t loc_id = ygets_hid_t(nArgs-1);
   char *name=YGetString(sp-nArgs+2);
   
-  long status;
+  hid_t id;
 
-  status=(long)H5Dopen((hid_t)loc_id, name);
+  id=H5Dopen(loc_id, name);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -529,13 +631,13 @@
 
 void Y__H5Dget_space(int nArgs)
 {
-  long dataset_id=YGetInteger(sp-nArgs+1);
-  
-  long status;
+  hid_t dataset_id = ygets_hid_t(nArgs-1);
 
-  status=(long)H5Dget_space((hid_t)dataset_id);
+  hid_t id;
 
-  PushIntValue(status);
+  id=H5Dget_space(dataset_id);
+
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -544,13 +646,13 @@
 
 void Y__H5Dget_type(int nArgs)
 {
-  long dataset_id=YGetInteger(sp-nArgs+1);
+  hid_t dataset_id = ygets_hid_t(nArgs-1);
   
-  long status;
+  hid_t id;
 
-  status=(long)H5Dget_type((hid_t)dataset_id);
+  id=H5Dget_type(dataset_id);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -560,11 +662,11 @@
 
 void Y__H5Dread(int nArgs)
 {
-  long dataset_id=YGetInteger(sp-nArgs+1);
-  long mem_type_id=YGetInteger(sp-nArgs+2);
-  long mem_space_id=YGetInteger(sp-nArgs+3);
-  long file_space_id=YGetInteger(sp-nArgs+4);
-  long xfer_plist_id=YGetInteger(sp-nArgs+5);
+  hid_t dataset_id = ygets_hid_t(nArgs-1);
+  hid_t mem_type_id = ygets_hid_t(nArgs-2);
+  hid_t mem_space_id = ygets_hid_t(nArgs-3);
+  hid_t file_space_id = ygets_hid_t(nArgs-4);
+  hid_t xfer_plist_id = ygets_hid_t(nArgs-5);
   
   long status;
 
@@ -582,11 +684,11 @@
 
 void Y__H5Dwrite(int nArgs)
 {
-  long dataset_id=YGetInteger(sp-nArgs+1);
-  long mem_type_id=YGetInteger(sp-nArgs+2);
-  long mem_space_id=YGetInteger(sp-nArgs+3);
-  long file_space_id=YGetInteger(sp-nArgs+4);
-  long xfer_plist_id=YGetInteger(sp-nArgs+5);
+  hid_t dataset_id = ygets_hid_t(nArgs-1);
+  hid_t mem_type_id = ygets_hid_t(nArgs-2);
+  hid_t mem_space_id = ygets_hid_t(nArgs-3);
+  hid_t file_space_id = ygets_hid_t(nArgs-4);
+  hid_t xfer_plist_id = ygets_hid_t(nArgs-5);
   
   long status;
 
@@ -603,11 +705,12 @@
 
 void Y__H5Sclose(int nArgs)
 {
-  long space_id=YGetInteger(sp-nArgs+1);
+  hid_t space_id = ygets_hid_t(nArgs-1);
   
   long status;
 
   status=(long)H5Sclose((hid_t)space_id);
+  yfree_hid_t(space_id);
 
   PushIntValue(status);
   PopTo(sp-nArgs-1);
@@ -620,11 +723,11 @@
 {
   long type=YGetInteger(sp-nArgs+1);
   
-  long status;
+  hid_t id;
 
-  status=(long)H5Screate((H5S_class_t)type);
+  id=H5Screate((H5S_class_t)type);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -633,7 +736,7 @@
 
 void Y__H5Sget_simple_extent_ndims(int nArgs)
 {
-  long space_id=YGetInteger(sp-nArgs+1);
+  hid_t space_id = ygets_hid_t(nArgs-1);
   
   long status;
 
@@ -648,7 +751,7 @@
 
 void Y__H5Sget_simple_extent_type(int nArgs)
 {
-  long space_id=YGetInteger(sp-nArgs+1);
+  hid_t space_id = ygets_hid_t(nArgs-1);
   
   long status;
 
@@ -675,7 +778,8 @@
   hsize_t hdims[5];  
   hsize_t hmaxdims[5];  
 
-  long status,i;
+  long i;
+  hid_t id;
 
   for (i=0;i<rank;i++) {
     hdims[i] = (hsize_t)dims[i];
@@ -684,9 +788,9 @@
     } else { hmaxdims[i] = (hsize_t)0; }
   }
 
-  status=(long)H5Screate_simple((int)rank, hdims, hmaxdims);
+  id=H5Screate_simple((int)rank, hdims, hmaxdims);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -697,7 +801,7 @@
 
 void Y__H5Sget_simple_extent_dims(int nArgs)
 {
-  long space_id=YGetInteger(sp-nArgs+1);
+  hid_t space_id = ygets_hid_t(nArgs-1);
   Dimension *dimsdims = 0;
   long *dims=YGet_L(sp-nArgs+2,0,&dimsdims);
   long ismaxdims = YNotNil(sp-nArgs+2);
@@ -734,13 +838,13 @@
 
 void Y__H5Tcopy(int nArgs)
 {
-  long type_id=YGetInteger(sp-nArgs+1);
+  hid_t type_id = ygets_hid_t(nArgs-1);
   
-  long status;
+  hid_t id;
 
-  status=(long)H5Tcopy((hid_t)type_id);
+  id=H5Tcopy(type_id);
 
-  PushIntValue(status);
+  ypush_hid_t(id);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
@@ -750,7 +854,7 @@
 
 void Y__H5Tget_class(int nArgs)
 {
-  long type_id=YGetInteger(sp-nArgs+1);
+  hid_t type_id = ygets_hid_t(nArgs-1);
   
   long status;
 
@@ -765,7 +869,7 @@
 
 void Y__H5Tget_size(int nArgs)
 {
-  long type_id=YGetInteger(sp-nArgs+1);
+  hid_t type_id = ygets_hid_t(nArgs-1);
   
   long status;
 
@@ -781,7 +885,7 @@
 
 void Y__H5Tset_cset(int nArgs)
 {
-  long type_id=YGetInteger(sp-nArgs+1);
+  hid_t type_id = ygets_hid_t(nArgs-1);
   long cset=YGetInteger(sp-nArgs+2);
   
   long status;
@@ -797,7 +901,7 @@
 
 void Y__H5Tset_size(int nArgs)
 {
-  long type_id=YGetInteger(sp-nArgs+1);
+  hid_t type_id = ygets_hid_t(nArgs-1);
   long size=YGetInteger(sp-nArgs+2);
 
   long status;
@@ -813,7 +917,7 @@
 
 void Y__H5Tset_strpad(int nArgs)
 {
-  long type_id=YGetInteger(sp-nArgs+1);
+  hid_t type_id = ygets_hid_t(nArgs-1);
   long strpad=YGetInteger(sp-nArgs+2);
   
   long status;
@@ -830,247 +934,247 @@
 
 void Y__H5T_C_S1(int nArgs)
 {
-  PushIntValue((long)H5T_C_S1);
+  ypush_hid_t(H5T_C_S1);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_NATIVE_CHAR(int nArgs)
 {
-  PushIntValue((long)H5T_NATIVE_CHAR);
+  ypush_hid_t(H5T_NATIVE_CHAR);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_NATIVE_SHORT(int nArgs)
 {
-  PushIntValue((long)H5T_NATIVE_SHORT);
+  ypush_hid_t(H5T_NATIVE_SHORT);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_NATIVE_INT(int nArgs)
 {
-  PushIntValue((long)H5T_NATIVE_INT);
+  ypush_hid_t(H5T_NATIVE_INT);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_NATIVE_LONG(int nArgs)
 {
-  PushIntValue((long)H5T_NATIVE_LONG);
+  ypush_hid_t(H5T_NATIVE_LONG);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_NATIVE_FLOAT(int nArgs)
 {
-  PushIntValue((long)H5T_NATIVE_FLOAT);
+  ypush_hid_t(H5T_NATIVE_FLOAT);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_NATIVE_DOUBLE(int nArgs)
 {
-  PushIntValue((long)H5T_NATIVE_DOUBLE);
+  ypush_hid_t(H5T_NATIVE_DOUBLE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_IEEE_F32BE(int nArgs)
 {
-  PushIntValue((long)H5T_IEEE_F32BE);
+  ypush_hid_t(H5T_IEEE_F32BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_IEEE_F32LE(int nArgs)
 {
-  PushIntValue((long)H5T_IEEE_F32LE);
+  ypush_hid_t(H5T_IEEE_F32LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_IEEE_F64BE(int nArgs)
 {
-  PushIntValue((long)H5T_IEEE_F64BE);
+  ypush_hid_t(H5T_IEEE_F64BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_IEEE_F64LE(int nArgs)
 {
-  PushIntValue((long)H5T_IEEE_F64LE);
+  ypush_hid_t(H5T_IEEE_F64LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_I8BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_I8BE);
+  ypush_hid_t(H5T_STD_I8BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_I8LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_I8LE);
+  ypush_hid_t(H5T_STD_I8LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_I16BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_I16BE);
+  ypush_hid_t(H5T_STD_I16BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_I16LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_I16LE);
+  ypush_hid_t(H5T_STD_I16LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_I32BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_I32BE);
+  ypush_hid_t(H5T_STD_I32BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_I32LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_I32LE);
+  ypush_hid_t(H5T_STD_I32LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_I64BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_I64BE);
+  ypush_hid_t(H5T_STD_I64BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_I64LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_I64LE);
+  ypush_hid_t(H5T_STD_I64LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_U8BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_U8BE);
+  ypush_hid_t(H5T_STD_U8BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_U8LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_U8LE);
+  ypush_hid_t(H5T_STD_U8LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_U16BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_U16BE);
+  ypush_hid_t(H5T_STD_U16BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_U16LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_U16LE);
+  ypush_hid_t(H5T_STD_U16LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_U32BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_U32BE);
+  ypush_hid_t(H5T_STD_U32BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_U32LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_U32LE);
+  ypush_hid_t(H5T_STD_U32LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_U64BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_U64BE);
+  ypush_hid_t(H5T_STD_U64BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_U64LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_U64LE);
+  ypush_hid_t(H5T_STD_U64LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_B8BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_B8BE);
+  ypush_hid_t(H5T_STD_B8BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_B8LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_B8LE);
+  ypush_hid_t(H5T_STD_B8LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_B16BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_B16BE);
+  ypush_hid_t(H5T_STD_B16BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_B16LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_B16LE);
+  ypush_hid_t(H5T_STD_B16LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_B32BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_B32BE);
+  ypush_hid_t(H5T_STD_B32BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_B32LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_B32LE);
+  ypush_hid_t(H5T_STD_B32LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_B64BE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_B64BE);
+  ypush_hid_t(H5T_STD_B64BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_B64LE(int nArgs)
 {
-  PushIntValue((long)H5T_STD_B64LE);
+  ypush_hid_t(H5T_STD_B64LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_STD_REF_OBJ(int nArgs)
 {
-  PushIntValue((long)H5T_STD_REF_OBJ);
+  ypush_hid_t(H5T_STD_REF_OBJ);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_UNIX_D32BE(int nArgs)
 {
-  PushIntValue((long)H5T_UNIX_D32BE);
+  ypush_hid_t(H5T_UNIX_D32BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_UNIX_D32LE(int nArgs)
 {
-  PushIntValue((long)H5T_UNIX_D32LE);
+  ypush_hid_t(H5T_UNIX_D32LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_UNIX_D64BE(int nArgs)
 {
-  PushIntValue((long)H5T_UNIX_D64BE);
+  ypush_hid_t(H5T_UNIX_D64BE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5T_UNIX_D64LE(int nArgs)
 {
-  PushIntValue((long)H5T_UNIX_D64LE);
+  ypush_hid_t(H5T_UNIX_D64LE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
 void Y__H5P_DATASET_CREATE(int nArgs)
 {
-  PushIntValue((long)H5P_DATASET_CREATE);
+  ypush_hid_t(H5P_DATASET_CREATE);
   PopTo(sp-nArgs-1);
   Drop(nArgs);
 }
--- a/hdf5.i
+++ b/hdf5.i
@@ -778,11 +778,10 @@
       gid = _H5Gopen(file,g(1:i)(sum));
       if (gid<0) {
         gid = _H5Gcreate(file,g(1:i)(sum),0);
-        status=_H5Gclose(gid);
-      }
-      if (gid<0) {
-        if (has2bclose) h5close,file;
-        error,"Unable to create group";
+        if (gid<0) {
+          if (has2bclose) h5close,file;
+          error,"Unable to create group";
+        }
       }
       status=_H5Gclose(gid);
     }
