fmttype.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 700 行 · 第 1/2 页

C
700
字号

static void fmtTypeFunction( arg_list *alist, VBUF *pvbuf, int num_def,
/*********************************************************************/
    FMT_CONTROL control )
{
    FMT_CONTROL arg_control;
    unsigned    i;
    unsigned    num_args;
    VBUF        working;

    VbufInit( &working );
    VStrNull( &working );
    VStrConcStr( &working, openFunction );
    num_args = alist->num_args;
    num_def = num_args - num_def;
    if( num_args == 0 ) {
        if( control & FF_USE_VOID ) {
            VStrConcStr( &working, typeName[TYP_VOID] );
        } else {
            VStrTruncWhite( &working );
        }
    } else {
        // only keep whether we want typedef names
        arg_control = control & ( FF_TYPEDEF_STOP | FF_ARG_NAMES );
        for( i = 0 ; i < num_def ; i++ ) {
            if( i > 0 ) {
                VStrTruncWhite( &working );
                VStrConcStr( &working, parameterSep );
            }
            fmtTypeArgument( alist->type_list[i], i, &working, arg_control );
        }
        if( num_args > num_def ) {
            VStrConcStr( &working, openSquareParen );
            for( ; i < num_args ; i++ ) {
                if( i > 0 ) {
                    VStrTruncWhite( &working );
                    VStrConcStr( &working, parameterSep );
                }
                fmtTypeArgument( alist->type_list[i], i, &working, arg_control );
            }
            VStrConcStr( &working, closeSquareParen );
        }
    }
    VStrConcStr( &working, closeFunction );
    fmtTypeFlag( alist->qualifier, &working, modifierFlags );
    VStrPrepStr( pvbuf, working.buf );
    VbufFree( &working );
}

static void fmtModifierTypeFlag( TYPE type, type_flag flag, VBUF *pvbuf )
/***********************************************************************/
{
    unsigned    i;
    type_flag   mask;

    for( i = 0 ; modifierFlags[i].name != NULL ; i++ ) {
        mask = modifierFlags[i].mask;
        if( (flag & mask) == mask ) {
            if( ( ( mask & TF1_MEM_MODEL ) == 0 ) ||
                  ( ( DefaultMemoryFlag( type ) & mask ) != mask ) ) {
                VStrConcStr( pvbuf, modifierFlags[i].name );
            }
        }
    }
}

static boolean willPrintModifier( TYPE type, type_flag flag )
/***********************************************************/
{
    unsigned    i;
    type_flag   mask;

    for( i = 0 ; modifierFlags[i].name != NULL ; i++ ) {
        mask = modifierFlags[i].mask;
        if( (flag & mask) == mask ) {
            if( ( ( mask & TF1_MEM_MODEL ) == 0 ) ||
                  ( ( DefaultMemoryFlag( type ) & mask ) != mask ) ) {
                return TRUE;
            }
        }
    }
    return FALSE;
}

static void fmtTypeChangeState( FMT_LR *curr, FMT_LR new,
/*******************************************************/
    VBUF *pprefix, VBUF *psuffix )
{
    if( new == RIGHT && *curr == LEFT ) {
        VStrConcStr( pprefix, openParen );
        VStrPrepStr( psuffix, closeParen );
    }
    *curr = new;
}

static void fmtTypeScope( SCOPE scope, VBUF *pprefix )
/****************************************************/
{
    VBUF name_scope;

    FormatScope( scope, &name_scope, FALSE );
    if( name_scope.buf != NULL ) {
        VStrConcStr( pprefix, name_scope.buf );
    }
    VbufFree( &name_scope );
}

static void fmtTemplateParms( TYPE class_type, VBUF *pprefix )
/************************************************************/
{
    VBUF parms;

    FormatTemplateParms( &parms, class_type );
    VStrConcStr( pprefix, parms.buf );
    VbufFree( &parms );
}

static void fmtUnboundTemplateParms( VBUF *pprefix, TYPE type )
{
    VBUF parms;

    FormatUnboundTemplateParms( &parms, type );
    VStrConcStr( pprefix, parms.buf );
    VbufFree( &parms );
}

static void fmtTypePush( FMT_INFO **pStackFMT, TYPE type, FMT_CONTROL control )
/*****************************************************************************/
{
    FMT_INFO *entry;
    FMT_INFO *main_function;

    main_function = NULL;
    while( type != NULL ) {
        entry = StackCarveAlloc( carveFMT, pStackFMT );
        entry->type = type;
        entry->main_function = FALSE;
        if( type->id == TYP_ENUM ) break;
        if( type->id == TYP_GENERIC ) break;
        if( type->id == TYP_CHAR ) break;
        if( type->id == TYP_BOOL ) break;
        if( type->id == TYP_TYPEDEF && control & FF_TYPEDEF_STOP ) break;
        if( type->id == TYP_FUNCTION ) {
            if( main_function == NULL ) {
                entry->main_function = TRUE;
                main_function = entry;
            }
            if( control & FF_DROP_RETURN ) break;
        }
        type = type->of;
    }
}

char *FormatErrorType( TYPE err_type )
/************************************/
{
    DbgAssert( err_type != NULL && err_type->id == TYP_ERROR );
    if( err_type->flag & TF1_SPECIAL_FMT ) {
        return( errFormats[ err_type->u.e.fmt ] );
    }
    return( typeName[ TYP_ERROR ] );
}

void FormatFunctionType( TYPE type, VBUF *pprefix, VBUF *psuffix, int num_def,
/****************************************************************************/
    FMT_CONTROL control )
{
    TYPE        top_type;
    TYPE        class_type;
    FMT_LR      lr_state;
    FMT_INFO    *StackFMT;
    FMT_INFO    *top;
    type_flag   flags;
    char        *name;
    AUX_INFO    *pragma;
    int         use_def;
    FMT_CONTROL fn_control;

    VbufInit( pprefix );
    VStrNull( pprefix );
    VbufInit( psuffix );
    VStrNull( psuffix );
    if( type == NULL ) {
        VStrConcStr( pprefix, nullType );
    } else {
        lr_state = RIGHT;
        StackFMT = NULL;
        fmtTypePush( &StackFMT, type, control );
        top = StackPop( &StackFMT );
        while( top ) {
            top_type = top->type;
            switch( top_type->id ) {
            case TYP_ERROR:
                VStrConcStr( pprefix, FormatErrorType( top_type ) );
                break;
            case TYP_BOOL:
            case TYP_CHAR:
            case TYP_SINT:
            case TYP_UINT:
            case TYP_SCHAR:
            case TYP_UCHAR:
            case TYP_WCHAR:
            case TYP_SSHORT:
            case TYP_SLONG:
            case TYP_ULONG:
            case TYP_SLONG64:
            case TYP_ULONG64:
            case TYP_FLOAT:
            case TYP_DOUBLE:
            case TYP_LONG_DOUBLE:
            case TYP_DOT_DOT_DOT:
            case TYP_VOID:
            case TYP_GENERIC:
                VStrConcStr( pprefix, typeName[top->type->id] );
                break;
            case TYP_USHORT:
                flags = top->type->flag;
                if( flags != TF1_NULL ) {
                    fmtTypeFlag( flags, pprefix, ushortFlags );
                } else {
                    VStrConcStr( pprefix, typeName[top->type->id] );
                }
                break;
            case TYP_POINTER:
                fmtTypeChangeState( &lr_state, RIGHT, pprefix, psuffix );
                flags = top->type->flag;
                if( flags != TF1_NULL ) {
                    fmtTypeFlag( flags, pprefix, pointerFlags );
                } else {
                    VStrConcStr( pprefix, typeName[top->type->id] );
                }
                break;
            case TYP_MEMBER_POINTER:
                fmtTypeChangeState( &lr_state, RIGHT, pprefix, psuffix );
                class_type = MemberPtrClass( top->type );
                if( class_type != NULL ) {
                    fmtTypeScope( class_type->u.c.scope->enclosing,
                                  pprefix );
                    name = SimpleTypeName( class_type );
                    if( name != NULL ) {
                        VStrConcStr( pprefix, name );
                    } else {
                        VStrConcStr( pprefix, memberPointer );
                    }
                } else {
                    VStrConcStr( pprefix, memberPointer );
                }
                VStrConcStr( pprefix, typeName[top->type->id] );
                break;
            case TYP_TYPEDEF:
                if( !(control & FF_TYPEDEF_STOP) ) break;
                // otherwise drop through
            case TYP_ENUM:
                fmtTypeScope( top->type->u.t.scope, pprefix );
                name = SimpleTypeName( top->type );
                if( name == NULL ) {
                    VStrConcStr( pprefix, typeName[top->type->id] );
                } else {
                    VStrConcStr( pprefix, name );
                    VStrConcStr( pprefix, whiteSpace );
                }
                break;
            case TYP_CLASS:
                fmtTypeScope( top->type->u.c.scope->enclosing, pprefix );
                flags = top->type->flag;
                name = SimpleTypeName( top->type );
                if( name == NULL ) {
                    if( flags != TF1_NULL ) {
                        fmtTypeFlag( flags, pprefix, classFlags );
                    } else {
                        VStrConcStr( pprefix, typeName[top->type->id] );
                    }
                } else {
                    VStrConcStr( pprefix, name );
                    if( flags & TF1_INSTANTIATION ) {
                        fmtTemplateParms( top->type, pprefix );
                    } else if( flags & TF1_UNBOUND ) {
                        fmtUnboundTemplateParms( pprefix, top->type );
                    }
                    VStrConcStr( pprefix, whiteSpace );
                }
                break;
            case TYP_BITFIELD:
                fmtTypeBitfield( top->type, psuffix );
                break;
            case TYP_FUNCTION:
                fmtTypeChangeState( &lr_state, LEFT, pprefix, psuffix );
                flags = top->type->flag;
                fmtTypeFlag( flags, pprefix, functionFlags );
                fmtTypePragma( top->type, pprefix );
                fn_control = control;
                if( top->main_function ) {
                    use_def = num_def;
                } else {
                    fn_control &= ~FF_ARG_NAMES;
                    use_def = 0;
                }
                fmtTypeFunction( TypeArgList( top->type )
                               , psuffix
                               , use_def
                               , fn_control );
                break;
            case TYP_ARRAY:
                fmtTypeChangeState( &lr_state, LEFT, pprefix, psuffix );
                fmtTypeArray( top->type, psuffix );
                break;
            case TYP_MODIFIER:
                flags = top->type->flag;
                pragma = top->type->u.m.pragma;
                if(( flags & TF1_DISPLAY ) == TF1_NULL && pragma == NULL ) {
                    lr_state = RIGHT;
                } else {
                    if( willPrintModifier( type, flags ) ||
                        willPrintBased( flags ) ) {
                        fmtTypeChangeState( &lr_state, RIGHT, pprefix, psuffix );
                        fmtModifierTypeFlag( type, flags, pprefix );
                        fmtTypeBased( top->type, pprefix );
                    } else {
                        lr_state = RIGHT;
                    }
                    fmtTypePragma( top->type, pprefix );
                }
                break;
            }
            CarveFree( carveFMT, top );
            top = StackPop( &StackFMT );
        }
        while( top ) {
            CarveFree( carveFMT, top );
            top = StackPop( &StackFMT );
        }
        VStrTruncWhite( psuffix );
    }
}


void FormatType( TYPE type, VBUF *pprefix, VBUF *psuffix )
/********************************************************/
{
    FormatFunctionType( type, pprefix, psuffix, 0, FormatTypeDefault );
}

void FormatTypeModFlags( type_flag flags, VBUF *pvbuf )
/*****************************************************/
{
    VbufInit( pvbuf );
    VStrNull( pvbuf );
    fmtTypeFlag( flags, pvbuf, modifierFlags );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?