--- edtk-1.1-orig/edtk/c_c_template.gsl	2003-05-20 08:43:51.000000000 +0900
+++ edtk-1.1/edtk/c_c_template.gsl	2006-04-05 19:10:51.664911464 +0900
@@ -415,7 +415,9 @@
 	/* Do not ever do async call if we're in pipe driver mode */
         do_async_call =  pipe_driver_p ? 0 : do_async_call;
 .  endif
-.  for func.arg where .noerlcall?"" <> 1
+.  define arg_valmap_index = 0
+.  for func.arg
+.  if .noerlcall?"" <> 1
 .    set_etype(ser_type?"unsigned-integer")
 .    if defined(.ser_size)
 .      define _tmp2 = .ser_size
@@ -438,14 +440,22 @@
 	EV_GET_UINT32(ev, &index, &p, &q);
 	if (index == -1 && $(.valmap_may_be_void?"0") == 1) {
 	    edtk_debug("%s: valmap $(.valmap_name) index %d = default value 0x%lx", __FUNCTION__, index, $(_tmp));
-	    c->i.$(.iname?.name) = $(_tmp);
-	    c->i.__valmap_$(.valmap_name)_index = -1;
+.          if .argtype?"" = "inout"
+            c->o.$(.iname?.name) = $(_tmp);
+.          else
+            c->i.$(.iname?.name) = $(_tmp);
+.          endif
+	    c->i.__valmap_indexes[$(arg_valmap_index)] = -1;
 	} else if (desc->valmap_$(.valmap_name)[index] == $(_tmp)) {
 	    goto error;
 	} else {
 	    edtk_debug("%s: valmap $(.valmap_name) index %d = 0x%lx", __FUNCTION__, index, desc->valmap_$(.valmap_name)[index]);
+.          if .argtype?"" = "inout"
+	    c->o.$(.iname?.name) = desc->valmap_$(.valmap_name)[index];
+.          else
 	    c->i.$(.iname?.name) = desc->valmap_$(.valmap_name)[index];
-	    c->i.__valmap_$(.valmap_name)_index = index;
+.          endif
+	    c->i.__valmap_indexes[$(arg_valmap_index)] = index;
 	}
 .    elsif _etype = "integer"
 .      if .argtype?"" = "inout"
@@ -494,6 +504,11 @@
 .    else
 	Argument type unknown!
 .    endif
+.  endif /* .noerlcall?"" <> 1 */
+.- Always increment the index of valmap args, even when noerlcall="1":
+.  if defined(.valmap_name)
+.    define arg_valmap_index = arg_valmap_index + 1
+.  endif
 .  endfor /* arg */
 .  for func.hack where place = "post-deserialize"
 .    if type = "verbatim"
@@ -509,13 +524,15 @@
 .    if _tmp > 0
 	/* Begin valmap flag adjustment */
 	pthread_mutex_lock(&desc->mutex);
+.      define arg_valmap_index = 0
 .      for func.arg where defined(.valmap_name?)
-	if (c->i.__valmap_$(.valmap_name)_index >= 0) {
-	    edtk_debug("%s: desc->valmap_$(.valmap_name)_flags[%d] = %d\\r\\n", __FUNCTION__, c->i.__valmap_$(.valmap_name)_index, desc->valmap_$(.valmap_name)_flags[c->i.__valmap_$(.valmap_name)_index]);
-	    assert(desc->valmap_$(.valmap_name)_flags[c->i.__valmap_$(.valmap_name)_index] == 0);
-	    desc->valmap_$(.valmap_name)_flags[c->i.__valmap_$(.valmap_name)_index] |= VALMAP_INUSE;
-	    edtk_debug("%s: INUSE set, desc->valmap_$(.valmap_name)_flags[%d] = %d\\r\\n", __FUNCTION__, c->i.__valmap_$(.valmap_name)_index, desc->valmap_$(.valmap_name)_flags[c->i.__valmap_$(.valmap_name)_index]);
+	if (c->i.__valmap_indexes[$(arg_valmap_index)] >= 0) {
+	    edtk_debug("%s: desc->valmap_$(.valmap_name)_flags[%d] = %d\\r\\n", __FUNCTION__, c->i.__valmap_indexes[$(arg_valmap_index)], desc->valmap_$(.valmap_name)_flags[c->i.__valmap_indexes[$(arg_valmap_index)]]);
+	    assert(desc->valmap_$(.valmap_name)_flags[c->i.__valmap_indexes[$(arg_valmap_index)]] == 0);
+	    desc->valmap_$(.valmap_name)_flags[c->i.__valmap_indexes[$(arg_valmap_index)]] |= VALMAP_INUSE;
+	    edtk_debug("%s: INUSE set, desc->valmap_$(.valmap_name)_flags[%d] = %d\\r\\n", __FUNCTION__, c->i.__valmap_indexes[$(arg_valmap_index)], desc->valmap_$(.valmap_name)_flags[c->i.__valmap_indexes[$(arg_valmap_index)]]);
 	}
+.       define arg_valmap_index = arg_valmap_index + 1
 .      endfor
 	pthread_mutex_unlock(&desc->mutex);
 	/* End valmap flag adjustment */
@@ -582,6 +599,22 @@
 	Unknown hack type '$(.type)'
 .        endif
 .      endfor /* hack */
+.  if defined(return.expect)
+        if (c->o.__expect) {
+.  endif
+.  define arg_valmap_index = 0
+.  for func.arg where defined(.valmap_name)
+.    if defined(.valmap_type) & .valmap_type = "stop"
+.      if .argtype = "out"
+#error Output-only argument $(.name) declared valmap_type="stop".
+.      endif
+        cleanup_valmap_$(.valmap_name)_index(desc, c->i.__valmap_indexes[$(arg_valmap_index)], 0);
+.    endif
+.    define arg_valmap_index = arg_valmap_index + 1
+.  endfor
+.  if defined(return.expect)
+        }
+.  endif
 .  for func.return
 .    if defined(.xreturn)
 .      for func.hack where place = "ready_async-pre-reply"
@@ -617,13 +650,6 @@
 	    desc->valmap_$(.valmap_name)[index] = c->o.$(.oname?.name);
 	    reply_ok_valmap(desc, am_valmap_$(.valmap_name), index);
 	}
-.      elsif .valmap_type = "stop"
-	cleanup_valmap_$(.valmap_name)_index(desc, c->i.__valmap_$(.valmap_name)_index, 0);
-.        if .ctype = "void"
-	reply_ok(desc);
-.        else
-	reply_ok_num(desc, c->o.$(.oname?.name));
-.        endif
 .      else
 	Unknown attribute valmap_type: $(.valmap_type)
 .      endif
@@ -736,7 +762,7 @@
 			 &$(.callcast?) c->o.$(oname?name)$(_comma)
 .      endif
 .    elsif .argtype = "inout"
-			 $(.callcast?) c->o.$(oname?name)$(_comma) /*inout*/
+			 &$(.callcast?) c->o.$(oname?name)$(_comma) /*inout*/
 .    elsif .argtype = "verbatim"
 $(.)
 .    else
@@ -760,14 +786,16 @@
 .      if _tmp > 0
     /* Begin valmap flag adjustment */
     pthread_mutex_lock(&c->desc->mutex);
+.        define arg_valmap_index = 0
 .        for func.arg where defined(.valmap_name?)
-    if (c->i.__valmap_$(.valmap_name)_index >= 0) {
-	c->desc->valmap_$(.valmap_name)_flags[c->i.__valmap_$(.valmap_name)_index] &= (~VALMAP_INUSE);
-	edtk_debug("%s: INUSE cleared, c->desc->valmap_$(.valmap_name)_flags[%d] = %d\\r\\n", __FUNCTION__, c->i.__valmap_$(.valmap_name)_index, c->desc->valmap_$(.valmap_name)_flags[c->i.__valmap_$(.valmap_name)_index]);
-	if (c->desc->valmap_$(.valmap_name)_flags[c->i.__valmap_$(.valmap_name)_index] & VALMAP_DELAYED_CLEANUP) {
-	    cleanup_valmap_$(.valmap_name)_index(c->desc, c->i.__valmap_$(.valmap_name)_index, 1);
+    if (c->i.__valmap_indexes[$(arg_valmap_index)] >= 0) {
+	c->desc->valmap_$(.valmap_name)_flags[c->i.__valmap_indexes[$(arg_valmap_index)]] &= (~VALMAP_INUSE);
+	edtk_debug("%s: INUSE cleared, c->desc->valmap_$(.valmap_name)_flags[%d] = %d\\r\\n", __FUNCTION__, c->i.__$(.name)_almap_$(.valmap_name)_index, c->desc->valmap_$(.valmap_name)_flags[c->i.__valmap_indexes[$(arg_valmap_index)]]);
+	if (c->desc->valmap_$(.valmap_name)_flags[c->i.__valmap_indexes[$(arg_valmap_index)]] & VALMAP_DELAYED_CLEANUP) {
+	    cleanup_valmap_$(.valmap_name)_index(c->desc, c->i.__valmap_indexes[$(arg_valmap_index)], 1);
 	}
     }
+.         define arg_valmap_index = arg_valmap_index + 1
 .        endfor
     pthread_mutex_unlock(&c->desc->mutex);
     /* End valmap flag adjustment */
@@ -970,6 +998,28 @@
 >$(-1.il) members++;
     elsif .etype = "float"
 >$(-1.il) Type float not implemented
+    elsif .etype = "valmap"
+.- FIXME: copied verbatim from the *_outputv implementation:
+.      if defined(.expect)
+.- FIXME: to implement:
+.-     if (! c->o.__expect) {
+.-         WHAT TO DO?
+.-     }
+.      endif
+.      if .valmap_type = "start"
+>$(-1.il) if (find_unused_$(.valmap_name)_index(desc, &valmap_index) < 0) {
+>$(-1.il)  reply_error(desc, ENOMEM);
+>$(-1.il)  return -1;
+>$(-1.il) } else {
+>$(-1.il)  desc->valmap_$(.valmap_name)[valmap_index] = c->o.$(.oname?.name);
+>$(-1.il) }
+.      else
+>$(-1.il)#error Unknown attribute valmap_type: $(.valmap_type)
+.      endif
+>$(-1.il) msgcount = LOAD_ATOM(msg, msgcount, am_valmap_$(.valmap_name));
+>$(-1.il) msgcount = LOAD_INT(msg, msgcount, valmap_index);
+>$(-1.il) msgcount = LOAD_TUPLE(msg, msgcount, 2);
+>$(-1.il) members++;
     elsif .etype = "tuple"
 .- Type tuple is handled by macro recursion, don't need to deal with it here.
     elsif .etype = "list"
@@ -1026,6 +1076,7 @@
     int			members = 0;
     char		*tmp = NULL;
     int                 i;
+    unsigned long	valmap_index;
     ErlDrvBinary	*tmpbin = NULL;
 
     tmp = tmp; tmpbin = tmpbin;
--- edtk-1.1-orig/edtk/c_h_template.gsl	2003-05-20 08:40:09.000000000 +0900
+++ edtk-1.1/edtk/c_h_template.gsl	2006-04-05 18:00:33.654146568 +0900
@@ -127,9 +127,19 @@
     ** and/or different flavors of callstate_t to avoid structure bloat.
     */
     struct {
-.for erldriver.valmap
-	int		__valmap_$(.name)_index;
+.define args_valmap_maxnum = 0
+.for erldriver.func
+.  define args_valmap_num = 0
+.  for .arg where defined(.valmap_name)
+.    define args_valmap_num = args_valmap_num + 1
+.  endfor
+.  if args_valmap_num > args_valmap_maxnum
+.    define args_valmap_maxnum = args_valmap_num
+.  endif
 .endfor
+.if args_valmap_maxnum > 0
+	int		__valmap_indexes[$(args_valmap_maxnum)];
+.endif
 .for erldriver.stash	/* At most 'stash' items, if defined */
 	unsigned long	__stash[$(.size)];
 .endfor

