home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 19
/
CD_ASCQ_19_010295.iso
/
vrac
/
adaada.zip
/
ADA.ZIP
/
ADA.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-23
|
13KB
|
522 lines
/* $Header: E:/new/ada.c_v 1.2 14 May 1992 14:08:12 ericj $
/*
*
* Copyright 1991 Premia Corp.
* All rights reserved
*
* This source code is provided to the purchaser of the product
* for the purpose of allowing the purchaser to customize and/or
* extend the functionality of the product. The source code
* remains the property of Premia Corp. with all rights reserved.
* Any modifications to the source code are considered derivative
* works and all rights thereto are reserved to Premia Corp. except
* that the purchaser may use the modified product in the same
* permitted manner as the unmodified product. It is expressly
* prohibited to distribute in any manner any part of the original
* source code, whether in source or object form, without the
* express written permission from Premia Corp.
*
* Owner:
* Premia Corporation
* 1075 NW Murray Blvd., Suite 268
* Portland OR 97229
*
*/
#include <windows.h>
#include <string.h>
#include <ctype.h>
#include "exports.h"
#include "startup.h"
#define MAX_BUF_LEN 100
static LPVOID _ada_hash_names = NIL; /* pointer to the hash table containing */
/* all 'ADA' keyword names. */
static LPVOID _ada_hash_templates = NIL; /* pointer to the hash table containing */
/* an abbreviated name and its template */
/* Define a structure to hold an abbreviation and the template to be
* expanded when the abbreviation is entered into the buffer.
* This structure will be the element in the hash table _ada_hash_templates.
*/
typedef struct _LanguageTemplate {
LPSTR abbrev;
LPSTR template;
} LanguageTemplate;
/* This string contains all keyword names which will be indented an extra level.
*/
LPSTR ADA_INDENT_STR = "PROC\377FOR\377IF\377SCAN\377WHILE\377THEN\377ELSE\377SWITCH\377";
/*
* _ada_templates[] contains the keyword abbreviation and the template for the
* abbreviation. To add a new name, insert it before the NIL entry or
* call _ada_assign_template().
*
* The special characters within the template are:
*
* \n - new line
* & - cursor position after template insertion
* @ - backspace
* \c - insert 'c' literally
*/
LanguageTemplate _ada_templates[] = {
{ "IF", "IF &\n\tTHEN\n@ENDIF" },
{ NIL, NIL },
};
/* Define the list of 'ADA' keyword names to appear in
* the keyword color if language coloring is enabled.
*/
LPSTR _ada_names[] = {
"if", "then", "endif",
"use", "width", "package",
NIL
};
static long _ada_in_comment( long offset );
void DLL _ada_init( void );
BOOL DLL _ada_expand( void );
void DLL _ada_language_colors_update( long firstline, long lastline );
void DLL _ada_language_colors( long numlines );
void DLL _ada_assign_template( LPSTR abbrev, LPSTR template );
void DLL _ada_add_keyword( LPSTR keyword );
BOOL DLL _ada_indent( void );
void DLL
_init()
{
_ada_init();
}
/*
** _ada_init()
*
* Initialize this module by exported any required functions and
* the hash tables needed to support indenting, template expandion
* and keyword coloring.
*/
void DLL
_ada_init( void )
{
static BOOL firstTime = TRUE;
int i;
if (firstTime)
{
LibExport( "BOOL _ada_expand");
LibExport( "_ada_assign_template LPSTR LPSTR");
LibExport( "_ada_add_keyword LPSTR");
LibExport( "BOOL _ada_indent");
LibExport( "_ada_language_colors_update long long");
LibExport( "_ada_language_colors long");
firstTime = FALSE;
/* Create a hash table to hold all of the 'ADA' keyword names.
*/
_ada_hash_names = HashCreateTable( 41 /* a prime # */, sizeof( LPSTR ), HASH_IGN_CASE );
i = 0;
while ( _ada_names[ i ] != NIL )
{
*(LPSTR XFAR *)HashGetEntry( _ada_hash_names, _ada_names[i], strlen( _ada_names[i] ) )
= StrNew( _ada_names[i] );
i++;
}
/* Create a hash table to hold all of the 'ADA' template names.
*/
_ada_hash_templates = HashCreateTable( 17 /* a prime # */, sizeof( LPSTR ), HASH_IGN_CASE );
i = 0;
while ( _ada_templates[ i ].abbrev != NIL )
{
_ada_assign_template( _ada_templates[i].abbrev, _ada_templates[i].template );
i++;
}
}
}
/*
** _ada_expand()
*
* DESCRIPTION:
* Attempts to perform 'ADA' language template expansion. This function
* is normally bound to the <SPACE> key. When invoked, it reads the
* previous word. If the word is in the list of defined templates,
* the template is extracted and inserted. Some characters in the
* templates have special meanings. They are:
*
* \n - new line
* & - cursor position after template insertion
* @ - backspace
* \ - take next character literally
*/
BOOL DLL
_ada_expand( void )
{
LPVOID htEntry;
LPSTR _ada_string;
LPSTR str;
long curline;
MarkSavePos();
curline = BufQCurrentLine();
/* Check to see if we are currently positioned inside a 'ADA' comment
*/
if (_ada_in_comment( -1L ) != -1)
goto _ada_expand_incomplete;
str = BufReadStr( 65535 ); /* read entire line */
_ada_string = StrTrim( str, " \t" );
StrFree( str );
if (!_ada_string)
goto _ada_expand_incomplete;
/* Search for a keyword match in the hash table.
*/
htEntry = HashFindEntry( _ada_hash_templates, _ada_string, strlen( _ada_string ) );
StrFree( _ada_string );
if (htEntry)
{
/* A template exists for the current keyword, delete the keyword
* and insert the template.
*/
MarkDropPos( 1 );
str = *(LPSTR*)htEntry;
BufDelToEOL();
_ext_expand_template( str );
}
else
goto _ada_expand_incomplete;
return TRUE;
_ada_expand_incomplete:
MarkRestorePos();
return FALSE;
}
/*
** _ada_language_colors_update()
*
* This function does an intermediate update of the colors within
* a range of line numbers (firstline and lastline). It must also
* determine if the first and last line specified are within a
* comment and act appropriately.
*/
void DLL
_ada_language_colors_update( long firstline, long lastline )
{
long startoff;
if (firstline && lastline)
{
/* Begin coloring at the previous comment if
* currently located in the middle of one.
*/
_PosInit( 0 );
if (firstline == 1)
_PosPrevLine( 0L );
else
_PosNextLine( firstline - 1);
startoff = _PosQOffset();
/* Clear all attributes for the line range and
* the reset them within _ada_language_colors.
*/
AttrSetColor( firstline, lastline, 1L, 0x7FFFFFFFL, 0 );
_PosInit( startoff );
_ada_language_colors( lastline - firstline + 1 );
}
}
/*
** _ada_language_colors()
*
* If numlines == -1, start from the top of the buffer and encode all of them,
* otherwise start at the current location of the number of lines specified.
*
* It is assumed that if numlines != -1, that _PosInit() has been called
* and numlines is relative to the current position.
*/
void DLL
_ada_language_colors( long numlines )
{
long startoff;
long startline;
long endoff;
long inc;
WORD ch;
LPSTR buf;
int i = 0;
int comment_color = ColorComments( -1 );
int keyword_color = ColorKeywords( -1 );
buf = (LPSTR)MemAlloc( MAX_BUF_LEN );
/* Start at the top of the buffer or current position
*/
if (numlines == -1)
{
_PosInit( 0 );
numlines = 0x7FFFFFFF;
}
else
{
startoff = _PosQOffset();
startline = _PosQLine();
endoff = _ada_in_comment( startoff );
if (endoff == -1)
_PosInit( startoff );
else
{
_PosInit( endoff );
numlines += (startline - _PosQLine());
}
}
ch = _PosCurrentChar();
startoff = _PosQOffset();
while ((ch != EOF_CHAR) && (numlines > 0))
{
if (ch == '\n')
numlines--;
if (ch == '"' || ch == '\'')
{
WORD quote = ch;
do
{
ch = _PosNextChar();
} while ((ch != EOF_CHAR) && (ch != '\n') && (ch != quote));
if (ch == quote)
ch = _PosNextChar();
continue;
}
else if (isalpha( ch ) || (ch == '_'))
{
WORD lastch = _PosPrevChar();
if (lastch != EOF_CHAR)
_PosNextChar();
i = 0;
startoff = _PosQOffset();
do
{
if (i < MAX_BUF_LEN)
buf[i++] = (char)ch;
ch = _PosNextChar();
} while (isalpha( ch ) || (ch == '_'));
if ((lastch != ' '
&& lastch != '\t'
&& lastch != '\r'
&& lastch != '\n'
&& !ispunct( lastch ))
|| (ch == '_'))
i = 0;
continue;
}
else if (i)
{
if (isalpha( buf[0] ))
{
if (HashFindEntry( _ada_hash_names, buf, i ))
{
endoff = _PosQOffset();
_PosInit( startoff );
_PosSetColor( keyword_color, endoff - startoff );
_PosInit( endoff );
}
}
i = 0;
}
if (ch == '-')
{
startoff = _PosQOffset();
ch = _PosNextChar();
if (ch == '-')
{
inc = _PosNextLine( 1 );
numlines--;
endoff = _PosQOffset();
_PosInit( startoff );
_PosSetColor( comment_color, endoff - startoff - inc );
_PosInit( endoff );
ch = _PosCurrentChar();
}
continue;
}
ch = _PosNextChar();
}
MemFree( buf );
}
void DLL
_ada_add_keyword( LPSTR keyword )
{
if (keyword && *keyword)
*(LPSTR XFAR *)HashGetEntry( _ada_hash_names, keyword, strlen( keyword ) )
= StrNew( keyword );
}
/*
** _ada_assign_template()
*
* PARAMETERS:
* abbrev - the keyword abreviation used to locate a template
* template - the encoded template string associated with 'abbrev'
*
* DESCRIPTION:
* Provide a means of adding or modifying 'ADA' template strings
* without changing the code.
*/
void DLL
_ada_assign_template( LPSTR abbrev, LPSTR template )
{
if (abbrev && template)
*(LPSTR XFAR *)HashGetEntry( _ada_hash_templates, abbrev, strlen( abbrev ) )
= StrNew( template );
}
/*
** _ada_indent()
*
* DESCRIPTION:
* Attempts to perform 'ADA' language smart indenting. This function
* will behave differently based on the following conditions:
*
* 1. Within a comment - normal indentation
*
* 2. Not positioned at end of line - normal indentation
*
* 3. Current line prefixed by a name in ADA_INDENT_STR - perform smart
* indentation.
*/
BOOL DLL
_ada_indent( void )
{
long curline;
long col;
LPSTR _ada_string;
LPSTR str;
long matchpos;
MarkSavePos();
curline = BufQCurrentLine();
/* Check to see if we are currently positioned inside a 'ADA' comment
*/
if (_ada_in_comment( -1L ) != -1)
goto _ada_indent_incomplete;
/* Not in a comment so indent according to the current 'ADA' construct.
*/
if (!SrchFind( "^[ \t]*[a-zA-Z_]+\\c([ \t]|$)", SEARCH_REGEX , NIL )
|| (BufQCurrentLine() != curline) )
goto _ada_indent_incomplete;
/* Read the keyword at the beginning of the current line.
*/
col = BufQCurrentCol();
SrchFind( "(^|[^a-zA-Z_])\\c[a-zA-Z_]", SEARCH_REGEX , NIL );
str = BufReadStr( col - BufQCurrentCol() );
_ada_string = StrTrim( str, " \t" );
StrFree( str );
/* Set prefix and suffix to \377 to perform a quick lookup of the name
*/
str = StrNew( "\377" );
_ada_string = StrAppend( _ada_string, str );
str = StrAppend( str, _ada_string );
StrFree( _ada_string );
matchpos = StrMatch( str, ADA_INDENT_STR, SEARCH_IGCASE | SEARCH_FORWARD, NIL );
StrFree( str );
if (!matchpos)
/* Not an 'ADA' keyword, do normal indentation. */
goto _ada_indent_incomplete;
MarkRestorePos();
_ext_insert_indented_EOL();
BufInsertChar( '\t' );
return TRUE;
_ada_indent_incomplete:
MarkRestorePos();
return FALSE;
}
/*-- Private functions --*/
/*
** _ada_in_comment()
*
* Determines whether or not the current position in the buffer is
* located within a 'ADA' comment by search backward for a // or /*
* comment declaration.
*
* Returns -1 if not in a comment
* >= 0 indicates the offset in the buffer where the comment begins
*/
static long
_ada_in_comment( long offset )
{
WORD ch;
/* Check to see if we are currently positioned inside an 'ADA' comment
*/
_PosInit( offset );
ch = _PosCurrentChar();
do
{
if (ch == '\n')
return -1;
else if (ch == '-')
{
ch = _PosPrevChar();
if (ch == '-')
return _PosQOffset(); /* currrent line is in a comment */
}
else
ch = _PosPrevChar();
} while (ch != EOF_CHAR);
return -1L;
}