sstyle.c

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

C
600
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Syntax highlighting control module.
*
****************************************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include "vi.h"
#include "colors.h"
#include "sstyle.h"
#include "lang.h"
#include "sstyle_c.h"
#include "sstyle_f.h"
#include "sstyle_h.h"
#include "sstyle_g.h"
#include "sstyle_m.h"


/*----- EXPORTS -----*/
type_style      SEType[ SE_NUMTYPES ];


static void getEOFText( ss_block *ss_new, char *text )
{
    if( *text ) {
        ss_new->type = SE_EOFTEXT;
        ss_new->len = strlen( text ) - 1;
        ss_new->end = ss_new->len;
    } else {
        ss_new->type = SE_WHITESPACE;
        ss_new->len = BEYOND_TEXT;
        ss_new->end = ss_new->len;
    }
}

static void getText( ss_block *ss_new, char *text )
{
    char    *start = text;

    if( *text == '\0' ) {
        ss_new->type = SE_WHITESPACE;
        ss_new->len = BEYOND_TEXT;
        return;
    }

    while( *text ) {
        text++;
    }
    ss_new->type = SE_TEXT;
    ss_new->len = text - start;
}

static void getNextBlock( ss_block *ss_new, char *text, int text_col,
                          line *line, linenum line_no )
{
    line_no = line_no;

    if( line == NULL ) {
        getEOFText( ss_new, text + text_col );
        return;
    }

    if( CurrentInfo == NULL ) return;

    switch( CurrentInfo->Language ) {
        case LANG_NONE:
            getText( ss_new, text + text_col );
            break;
        case LANG_HTML:
        case LANG_WML:
            GetHTMLBlock( ss_new, text + text_col, text_col );
            break;
        case LANG_GML:
            GetGMLBlock( ss_new, text + text_col, text_col );
            break;
        case LANG_MAKEFILE:
            GetMkBlock( ss_new, text + text_col, text_col );
            break;
        case LANG_FORTRAN:
            GetFORTRANBlock( ss_new, text + text_col, text_col );
            break;
        case LANG_C:
        case LANG_CPP:
        case LANG_JAVA:
        case LANG_SQL:
        case LANG_BAT:
        case LANG_BASIC:
        case LANG_PERL:
        case LANG_DBTEST:
        case LANG_USER:
        default:
            GetCBlock( ss_new, text + text_col, line, line_no );
            break;
    }

    /* GetCBlock, GetFORTRANBlock, GetHTMLBlock and getText fill in only ss->len.
       use this to get an index into the text, stored in ss->end.
    */
    ss_new->end = ss_new->len;
    if( ss_new->len != BEYOND_TEXT ) {
        ss_new->end = ss_new->len + text_col - 1;
    }
}

void addSelection( ss_block *ss_start, linenum line_no )
{
    int         sel_start_col, sel_end_col;
    int         sel_start_line, sel_end_line;
    int         tmp, i;
    bool        swap_cols;
    ss_block    *ss, *ss2;
    static ss_block ss_copy[ MAX_SS_BLOCKS ];
    ss_block    ss_save;

    // don't call me unless something selected
    assert( SelRgn.selected );
    i = 0;

    // get nicely ordered values from SelRgn
    sel_end_col = VirtualCursorPosition2( SelRgn.end_col ) - 1;
    sel_start_col = SelRgn.start_col_v - 1;
    #ifdef __WIN__
    if( EditFlags.RealTabs ){
        sel_end_col = SelRgn.end_col - 1;
        sel_start_col = SelRgn.start_col- 1;
    }
    #endif
    swap_cols = FALSE;
    if( SelRgn.start_line > SelRgn.end_line ) {
        sel_start_line = SelRgn.end_line;
        sel_end_line = SelRgn.start_line;
        swap_cols = TRUE;
    } else {
        sel_start_line = SelRgn.start_line;
        sel_end_line = SelRgn.end_line;
    }
    if( SelRgn.start_line == SelRgn.end_line &&
        sel_start_col > sel_end_col ) {
        swap_cols = TRUE;
    }
    if( swap_cols ) {
        tmp = sel_start_col;
        sel_start_col = sel_end_col;
        sel_end_col = tmp;
    }

    // select entire line
    if( ( sel_start_line < line_no && sel_end_line > line_no ) ||
        ( SelRgn.lines &&
            ( sel_start_line == line_no || sel_end_line == line_no ) ) ) {
        ss_start->type = SE_SELECTION;
        ss_start->end = ss_start->len = BEYOND_TEXT;
        return;
    }

    // select subset within current line
    if( sel_start_line == sel_end_line && sel_start_line == line_no ) {
        if( sel_start_col == sel_end_col ) {
            return;
        }
        ss2 = ss_copy;
        ss = ss_start;
        while( ss->end < sel_start_col ) {
            *ss2 = *ss;
            ss2++;
            ss++;
        }
        ss_save = *ss;
        if( ( ss == ss_start && sel_start_col > 0 ) ||
            ( ss != ss_start && ( ss - 1 )->end + 1 != sel_start_col ) ) {
            ss2->type = ss->type;
            ss2->len = ss->len - ( ss->end - sel_start_col + 1 );
            if( ss2->len != 0 ) {
                ss2->end = sel_start_col - 1;
                ss2++;
            }
        }
        ss2->type = SE_SELECTION;
        ss2->len = sel_end_col - sel_start_col;
        ss2->end = sel_end_col - 1;
        ss2++;
        if( ss_save.end >= sel_end_col ) {
            ss2->type = ss_save.type;
            ss2->len = ss_save.end - sel_end_col + 1;
            if( ss2->len != 0 ) {
                ss2->end = ss_save.end;
                ss2++;
            }
        } else {
            while( ss->end < sel_end_col ) {
                ss++;
            }
            if( ss->end >= sel_end_col ) {
                ss2->type = ss->type;
                ss2->len = ss->end - sel_end_col + 1;
                if( ss2->len != 0 ) {
                    ss2->end = ss->end;
                    ss2++;
                }
            }
        }
        if( ss->end != BEYOND_TEXT ) {
            do {
                ss++;
                *ss2 = *ss;
                ss2++;
            } while( ss->end != BEYOND_TEXT );
        }
        memcpy( ss_start, ss_copy, MAX_SS_BLOCKS * sizeof( ss_block ) );
        return;
    }

    // select from start of selection to far right
    if( sel_start_line == line_no ) {
        ss = ss_start;
        while( ss->end < sel_start_col ) {
            ss++;
        }
        if( ( ss == ss_start && sel_start_col > 0 ) ||
            ( ss != ss_start && ( ss - 1 )->end + 1 != sel_start_col ) ) {
            // split block just to the left
            ss->len -= ( ss->end - sel_start_col + 1 );
            if( ss->len != 0 ) {
                ss->end = sel_start_col - 1;
                ss++;
            }
        }
        ss->type = SE_SELECTION;
        ss->end = ss->len = BEYOND_TEXT;
        return;
    }

    // select from far left to end of selection
    if( sel_end_line == line_no && sel_end_col != 0 ) {
        ss = ss_start;
        while( ss->end < sel_end_col ) {
            ss++;
            i++;
        }
        ss2 = ss_start + 1;
        if( ss->end >= sel_end_col ) {
            ss_save.type = ss->type;
            ss_save.len = ss->end - sel_end_col + 1;
            if( ss_save.len != 0 ) {
                ss_save.end = ss->end;
                ss2++;
                i++;
            }
        }
        memmove( ss2, ss + 1, ( MAX_SS_BLOCKS - i - 1 ) * sizeof( ss_block ) );
        ss_start->type = SE_SELECTION;
        ss_start->end = sel_end_col - 1;
        ss_start->len = sel_end_col;
        if( ss2 == ss_start + 2 ) {
            *( ss_start + 1 ) = ss_save;
        }
        return;
    }

    // otherwise nothing is selected on this line
}

void fixSelection( ss_block *ss_start, int start_col )
{
    ss_block    *ss;
    int i = MAX_SS_BLOCKS;

    ss = ss_start;
    while( ss->end < start_col ) {
        ss++;
        i--;

⌨️ 快捷键说明

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