allow .feature to both enable and disable

This commit is contained in:
bbbradsmith
2023-02-24 18:00:58 -05:00
parent a299ef4210
commit da150aeeac
5 changed files with 56 additions and 50 deletions

View File

@@ -2746,15 +2746,19 @@ See: <tt><ref id=".ASCIIZ" name=".ASCIIZ"></tt>,<tt><ref id=".CHARMAP" name=".CH
This directive may be used to enable one or more compatibility features This directive may be used to enable one or more compatibility features
of the assembler. While the use of <tt/.FEATURE/ should be avoided when of the assembler. While the use of <tt/.FEATURE/ should be avoided when
possible, it may be useful when porting sources written for other possible, it may be useful when porting sources written for other
assemblers. There is no way to switch a feature off, once you have assemblers. After the feature name an optional '+' or '-' may specify whether
enabled it, so using to enable or disable the feature (enable if omitted). Multiple features may be
enabled, separated by commas. Examples:
<tscreen><verb> <tscreen><verb>
.FEATURE xxx ; enable c_comments
.feature c_comments
.feature c_comments +
; enable force_range, disable underline_in_numbers, enable labels_without_colons
.feature force_range, underline_in_numbers -, labels_without_colons +
.feature force_range +, underline_in_numbers off, labels_without_colons on
</verb></tscreen> </verb></tscreen>
will enable the feature until end of assembly is reached.
The following features are available: The following features are available:
<descrip> <descrip>

View File

@@ -98,38 +98,30 @@ feature_t FindFeature (const StrBuf* Key)
feature_t SetFeature (const StrBuf* Key) void SetFeature (feature_t Feature, unsigned char On)
/* Find the feature and set the corresponding flag if the feature is known. /* Set the corresponding feature flag if Feature is valid.
** In any case, return the feature found. An invalid Key will return
** FEAT_UNKNOWN.
*/ */
{ {
/* Map the string to an enum value */
feature_t Feature = FindFeature (Key);
/* Set the flags */ /* Set the flags */
switch (Feature) { switch (Feature) {
case FEAT_DOLLAR_IS_PC: DollarIsPC = 1; break; case FEAT_DOLLAR_IS_PC: DollarIsPC = On; break;
case FEAT_LABELS_WITHOUT_COLONS: NoColonLabels = 1; break; case FEAT_LABELS_WITHOUT_COLONS: NoColonLabels = On; break;
case FEAT_LOOSE_STRING_TERM: LooseStringTerm = 1; break; case FEAT_LOOSE_STRING_TERM: LooseStringTerm = On; break;
case FEAT_LOOSE_CHAR_TERM: LooseCharTerm = 1; break; case FEAT_LOOSE_CHAR_TERM: LooseCharTerm = On; break;
case FEAT_AT_IN_IDENTIFIERS: AtInIdents = 1; break; case FEAT_AT_IN_IDENTIFIERS: AtInIdents = On; break;
case FEAT_DOLLAR_IN_IDENTIFIERS: DollarInIdents = 1; break; case FEAT_DOLLAR_IN_IDENTIFIERS: DollarInIdents = On; break;
case FEAT_LEADING_DOT_IN_IDENTIFIERS: LeadingDotInIdents= 1; break; case FEAT_LEADING_DOT_IN_IDENTIFIERS: LeadingDotInIdents= On; break;
case FEAT_ORG_PER_SEG: OrgPerSeg = 1; break; case FEAT_ORG_PER_SEG: OrgPerSeg = On; break;
case FEAT_PC_ASSIGNMENT: PCAssignment = 1; break; case FEAT_PC_ASSIGNMENT: PCAssignment = On; break;
case FEAT_MISSING_CHAR_TERM: MissingCharTerm = 1; break; case FEAT_MISSING_CHAR_TERM: MissingCharTerm = On; break;
case FEAT_UBIQUITOUS_IDENTS: UbiquitousIdents = 1; break; case FEAT_UBIQUITOUS_IDENTS: UbiquitousIdents = On; break;
case FEAT_C_COMMENTS: CComments = 1; break; case FEAT_C_COMMENTS: CComments = On; break;
case FEAT_FORCE_RANGE: ForceRange = 1; break; case FEAT_FORCE_RANGE: ForceRange = On; break;
case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break; case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= On; break;
case FEAT_ADDRSIZE: AddrSize = 1; break; case FEAT_ADDRSIZE: AddrSize = On; break;
case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = 1; break; case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = On; break;
case FEAT_STRING_ESCAPES: StringEscapes = 1; break; case FEAT_STRING_ESCAPES: StringEscapes = On; break;
case FEAT_LONG_JSR_JMP_RTS: LongJsrJmpRts = 1; break; case FEAT_LONG_JSR_JMP_RTS: LongJsrJmpRts = On; break;
default: /* Keep gcc silent */ break; default: break;
} }
/* Return the value found */
return Feature;
} }

View File

@@ -87,10 +87,8 @@ feature_t FindFeature (const StrBuf* Key);
** feature is invalid, return FEAT_UNKNOWN. ** feature is invalid, return FEAT_UNKNOWN.
*/ */
feature_t SetFeature (const StrBuf* Key); void SetFeature (feature_t Feature, unsigned char On);
/* Find the feature and set the corresponding flag if the feature is known. /* Set the corresponding feature flag if Feature is valid.
** In any case, return the feature found. An invalid Key will return
** FEAT_UNKNOWN.
*/ */

View File

@@ -489,12 +489,15 @@ static void OptDebugInfo (const char* Opt attribute ((unused)),
static void OptFeature (const char* Opt attribute ((unused)), const char* Arg) static void OptFeature (const char* Opt attribute ((unused)), const char* Arg)
/* Set an emulation feature */ /* Set an emulation feature */
{ {
/* Make a string buffer from Arg */ /* Make a string buffer from Arg and use it to find the feature. */
StrBuf Feature; StrBuf StrFeature;
feature_t Feature = FindFeature (SB_InitFromString (&StrFeature, Arg));
/* Set the feature, check for errors */ /* Enable the feature, check for errors */
if (SetFeature (SB_InitFromString (&Feature, Arg)) == FEAT_UNKNOWN) { if (Feature == FEAT_UNKNOWN) {
AbEnd ("Illegal emulation feature: '%s'", Arg); AbEnd ("Illegal emulation feature: '%s'", Arg);
} else {
SetFeature (Feature, 1);
} }
} }

View File

@@ -1023,7 +1023,10 @@ static void DoFatal (void)
static void DoFeature (void) static void DoFeature (void)
/* Switch the Feature option */ /* Switch the Feature option */
{ {
/* Allow a list of comma separated keywords */ feature_t Feature;
unsigned char On;
/* Allow a list of comma separated feature keywords with optional +/- or ON/OFF */
while (1) { while (1) {
/* We expect an identifier */ /* We expect an identifier */
@@ -1034,18 +1037,24 @@ static void DoFeature (void)
/* Make the string attribute lower case */ /* Make the string attribute lower case */
LocaseSVal (); LocaseSVal ();
Feature = FindFeature(&CurTok.SVal);
/* Set the feature and check for errors */ if (Feature == FEAT_UNKNOWN) {
if (SetFeature (&CurTok.SVal) == FEAT_UNKNOWN) {
/* Not found */ /* Not found */
ErrorSkip ("Invalid feature: '%m%p'", &CurTok.SVal); ErrorSkip ("Invalid feature: '%m%p'", &CurTok.SVal);
return; return;
} else { }
/* Skip the keyword */
NextTok (); NextTok ();
/* Optional +/- or ON/OFF */
On = 1;
if (CurTok.Tok != TOK_COMMA && !TokIsSep (CurTok.Tok)) {
SetBoolOption(&On);
} }
/* Allow more than one keyword */ /* Apply feature setting. */
SetFeature (Feature, On);
/* Allow more than one feature separated by commas. */
if (CurTok.Tok == TOK_COMMA) { if (CurTok.Tok == TOK_COMMA) {
NextTok (); NextTok ();
} else { } else {