static void 
decomposeValueWithTree(xmlrpc_env *                  const envP,
                       xmlrpc_value *                const valueP,
                       bool                          const oldstyleMemMgmt,
                       const struct decompTreeNode * const decompRootP) {
/*----------------------------------------------------------------------------
   Decompose XML-RPC value *valueP, given the decomposition tree
   *decompRootP.  The decomposition tree tells what structure *valueP
   is expected to have and where to put the various components of it
   (e.g. it says "it's an array of 3 integers.  Put their values at
   locations x, y, and z")
-----------------------------------------------------------------------------*/
    switch (decompRootP->formatSpecChar) {
    case '-':
        /* There's nothing to validate or return */
        break;
    case 'i':
        xmlrpc_read_int(envP, valueP, decompRootP->store.Tinteger.valueP);
        break;

    case 'b':
        xmlrpc_read_bool(envP, valueP, decompRootP->store.Tbool.valueP);
        break;

    case 'd':
        xmlrpc_read_double(envP, valueP, decompRootP->store.Tdouble.valueP);
        break;

    case 't':
        xmlrpc_read_datetime_sec(envP, valueP,
                                 decompRootP->store.TdatetimeT.valueP);
        break;

    case '8':
        readDatetime8Str(envP, valueP, decompRootP->store.Tdatetime8.valueP,
                         oldstyleMemMgmt);
        break;

    case 's':
        if (decompRootP->store.Tstring.sizeP)
            readStringLp(envP, valueP,
                         decompRootP->store.Tstring.sizeP,
                         decompRootP->store.Tstring.valueP,
                         oldstyleMemMgmt);
        else
            readString(envP, valueP, decompRootP->store.Tstring.valueP,
                       oldstyleMemMgmt);
        break;

    case 'w':
#if HAVE_UNICODE_WCHAR
        if (decompRootP->store.Tstring.sizeP)
            readStringWLp(envP, valueP,
                          decompRootP->store.TwideString.sizeP,
                          decompRootP->store.TwideString.valueP,
                          oldstyleMemMgmt);
        else
            readStringW(envP, valueP, decompRootP->store.TwideString.valueP,
                        oldstyleMemMgmt);
#else
        XMLRPC_ASSERT(false);
#endif /* HAVE_UNICODE_WCHAR */
        break;
        
    case '6':
        readBase64(envP, valueP,
                   decompRootP->store.TbitString.sizeP,
                   decompRootP->store.TbitString.valueP,
                   oldstyleMemMgmt);
        break;

    case 'n':
        xmlrpc_read_nil(envP, valueP);
        break;

    case 'I':
        xmlrpc_read_i8(envP, valueP, decompRootP->store.Ti8.valueP);
        break;

    case 'p':
        xmlrpc_read_cptr(envP, valueP, decompRootP->store.Tcptr.valueP);
        break;

    case 'V':
        *decompRootP->store.Tvalue.valueP = valueP;
        if (!oldstyleMemMgmt)
            xmlrpc_INCREF(valueP);
        break;

    case 'A':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_ARRAY)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the 'A' specifier requires type ARRAY",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else {
            *decompRootP->store.TarrayVal.valueP = valueP;
            if (!oldstyleMemMgmt)
                xmlrpc_INCREF(valueP);
        }
        break;

    case 'S':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_STRUCT)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the 'S' specifier requires type STRUCT.",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else {
            *decompRootP->store.TstructVal.valueP = valueP;
            if (!oldstyleMemMgmt)
                xmlrpc_INCREF(valueP);
        }
        break;

    case '(':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_ARRAY)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the '(...)' specifier requires type ARRAY",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else
            parsearray(envP, valueP, decompRootP->store.Tarray,
                       oldstyleMemMgmt);
        break;

    case '{':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_STRUCT)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the '{...}' specifier requires type STRUCT",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else
            parsestruct(envP, valueP, decompRootP->store.Tstruct,
                        oldstyleMemMgmt);
        break;

    default:
        /* Every format character that is allowed in a decomposition tree
           node is handled above.
        */
        XMLRPC_ASSERT(false);
    }
}
// compilation d'un type
// [name] -> 0
int Compiler::parsetype()
{
	int k;
//	PRINTF(m)(LOG_DEVCORE,"type %s\n",STRSTART(VALTOPNT(STACKGET(m,0))));

	char* name=STRSTART(VALTOPNT(STACKGET(m,0)));
	// création des variables de travail
	if (k=STACKPUSH(m,NIL)) return k; // LOCALS
	locals=STACKREF(m);

	newref=searchemptytype(PNTTOVAL(newpackage),name);
	int mergetype=1;
	if (newref)
	{
		if (k=createnodetypecore(TABGET(VALTOPNT(TABGET(newref,REF_TYPE)),TYPEHEADER_LENGTH+1))) return k;
	}
	else
	{
		mergetype=0;
		if (k=createnodetypecore(STACKGET(m,1))) return k;
		newref=MALLOCCLEAR(m,REF_LENGTH);
		if (!newref) return MTLERR_OM;
		TABSET(m,newref,REF_CODE,INTTOVAL(CODE_EMPTYTYPE));
		TABSET(m,newref,REF_TYPE,STACKGET(m,0));
		 if (k=STACKPUSH(m,PNTTOVAL(newref))) return MTLERR_OM;	// [newtyp local name]
		addreftopackage(newref,newpackage);
		STACKDROP(m);
	}

	int narg=0;
	if (parser->next(0))
	{
		if (strcmp(parser->token,"(")) parser->giveback();
		else
		{
			do
			{
				if (!parser->next(0))
				{
					PRINTF(m)(LOG_COMPILER,"Compiler : parameter or ')' expected (found EOF)\n");
					return MTLERR_SN;
				}
				if (islabel(parser->token))
				{
					if (k=createnodetype(TYPENAME_UNDEF)) return k;
					if (k=addlabel(locals,parser->token,STACKGET(m,0),INTTOVAL(narg++))) return k;
				}
				else if (strcmp(parser->token,")"))
				{
					PRINTF(m)(LOG_COMPILER,"Compiler : parameter or ')' expected (found '%s')\n",parser->token);
					return MTLERR_SN;
				}
			} while(strcmp(parser->token,")"));
			if (k=DEFTAB(m,narg)) return k;
			TABSET(m,VALTOPNT(STACKGET(m,1)),TYPEHEADER_LENGTH,STACKGET(m,0));
			STACKDROP(m);
		}
	}
	if (!mergetype) STACKDROP(m);
	else if (k=unif(VALTOPNT(STACKPULL(m)),VALTOPNT(TABGET(newref,REF_TYPE)))) return k;

	if (!parser->next(0))
	{
		PRINTF(m)(LOG_COMPILER,"Compiler : '=' or ';;' expected (found EOF)\n");
		return MTLERR_SN;
	}
	if (!strcmp(parser->token,"="))
	{
		if (!parser->next(0))
		{
			PRINTF(m)(LOG_COMPILER,"Compiler : uncomplete type definition (found EOF)\n");
			return MTLERR_SN;
		}
		if (!strcmp(parser->token,"[")) return parsestruct();
		parser->giveback();
		return parsesum();
	}
	else if (!strcmp(parser->token,";;"))
	{
		STACKDROPN(m,2);
		outputbuf->reinit();
		outputbuf->printf("Compiler : uncompleted type : ");
		echograph(outputbuf,VALTOPNT(TABGET(newref,REF_TYPE)));
		PRINTF(m)(LOG_COMPILER,"%s\n",outputbuf->getstart());
		return 0;
	}
	PRINTF(m)(LOG_COMPILER,"Compiler : '=' or ';;' expected (found '%s')\n",parser->token);
	return MTLERR_SN;
}