/*
 * IDL Compiler
 *
 * Copyright 2002 Ove Kaaven
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#ifndef __WIDL_HEADER_H
#define __WIDL_HEADER_H

#include "typetree.h"

extern int is_ptrchain_attr(const var_t *var, enum attr_type t);
extern int is_aliaschain_attr(const type_t *var, enum attr_type t);
extern int is_attr(const attr_list_t *list, enum attr_type t);
extern void *get_attrp(const attr_list_t *list, enum attr_type t);
extern unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
extern int is_void(const type_t *t);
extern int is_conformant_array(const type_t *t);
extern int is_declptr(const type_t *t);
extern const char* get_name(const var_t *v);
extern void write_type_left(FILE *h, type_t *t, int declonly);
extern void write_type_right(FILE *h, type_t *t, int is_field);
extern void write_type_decl(FILE *f, type_t *t, const char *name, const char *prefix);
extern void write_type_decl_left(FILE *f, type_t *t);
extern unsigned int get_context_handle_offset( const type_t *type );
extern unsigned int get_generic_handle_offset( const type_t *type );
extern int needs_space_after(type_t *t);
extern int is_object(const type_t *iface);
extern int is_local(const attr_list_t *list);
extern int count_methods(const type_t *iface);
extern int need_stub(const type_t *iface);
extern int need_proxy(const type_t *iface);
extern int need_inline_stubs(const type_t *iface);
extern int need_stub_files(const statement_list_t *stmts);
extern int need_proxy_file(const statement_list_t *stmts);
extern int need_proxy_delegation(const statement_list_t *stmts);
extern int need_inline_stubs_file(const statement_list_t *stmts);
extern const var_t *is_callas(const attr_list_t *list);

#define FILTER_NONE 0
#define FILTER_IN 1
#define FILTER_OUT 2

extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent, int filter);
extern void write_array(FILE *h, array_dims_t *v, int field);
extern const type_t* get_explicit_generic_handle_type(const var_t* var);
extern const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
                                         unsigned char *explicit_fc, unsigned char *implicit_fc );
extern int has_out_arg_or_return(const var_t *func);
extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
                       const UUID *uuid);
extern int is_const_decl(const var_t *var);

static inline int last_ptr(const type_t *type)
{
    return is_ptr(type) && !is_declptr(type_pointer_get_ref(type));
}

static inline int last_array(const type_t *type)
{
    return is_array(type) && !is_array(type_array_get_element(type));
}

static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
{
    return ((is_attr(attrs, ATTR_STRING) || is_aliaschain_attr(type, ATTR_STRING))
            && (last_ptr(type) || last_array(type)));
}

static inline int is_context_handle(const type_t *type)
{
    const type_t *t;
    for (t = type;
         is_ptr(t) || type_is_alias(t);
         t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
        if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
            return 1;
    return 0;
}

#endif
