aboutsummaryrefslogtreecommitdiff
path: root/gcc/cobol/parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cobol/parse.y')
-rw-r--r--gcc/cobol/parse.y415
1 files changed, 306 insertions, 109 deletions
diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index c497b8f..9187a59 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -55,6 +55,41 @@
const char *alpha, *national;
};
+ struct label_pair_t {
+ cbl_label_t *from, *to;
+ };
+
+class locale_tgt_t {
+ char user_system_default;
+ std::vector<int> categories;
+ public:
+ locale_tgt_t() : user_system_default('\0') {}
+ locale_tgt_t( int category )
+ : user_system_default('\0')
+ , categories(1, category)
+ {}
+ locale_tgt_t operator=( int ch ) {
+ assert(categories.empty());
+ switch(ch) {
+ case 'S': case 'U':
+ user_system_default = ch;
+ return *this;
+ }
+ gcc_unreachable();
+ }
+ locale_tgt_t push_back( int token ) {
+ categories.push_back(token);
+ return *this;
+ }
+
+ bool is_default() const { return 0 < user_system_default; }
+ char default_of() const {
+ assert(categories.empty());
+ return user_system_default;
+ }
+ const std::vector<int>& lc_categories() const { return categories; }
+};
+
class literal_t {
size_t isym;
public:
@@ -65,9 +100,7 @@
bool empty() const { return data == NULL; }
size_t isymbol() const { return isym; }
- const char * symbol_name() const {
- return isym? cbl_field_of(symbol_at(isym))->name : "";
- }
+ const char * symbol_name() const;
literal_t&
set( size_t len, char *data, const char prefix[] ) {
@@ -76,17 +109,8 @@
return *this;
}
- literal_t&
- set( const cbl_field_t * field ) {
- assert(field->has_attr(constant_e));
- assert(is_literal(field));
-
- set_prefix( "", 0 );
- set_data( field->data.capacity,
- const_cast<char*>(field->data.initial),
- field_index(field) );
- return *this;
- }
+ literal_t& set( const cbl_field_t * field );
+
literal_t&
set_data( size_t len, char *data, size_t isym = 0 ) {
this->isym = isym;
@@ -99,36 +123,8 @@
}
return *this;
}
- literal_t&
- set_prefix( const char *input, size_t len ) {
- encoding = current_encoding('A');
- assert(len < sizeof(prefix));
- std::fill(prefix, prefix + sizeof(prefix), '\0');
- std::transform(input, input + len, prefix, toupper);
- switch(prefix[0]) {
- case '\0': case 'Z':
- encoding = current_encoding('A');
- break;
- case 'N':
- encoding = current_encoding('N');
- if( 'X' == prefix[1] ) {
- cbl_unimplemented("NX literals");
- }
- break;
- case 'G':
- cbl_unimplemented("DBCS encoding not supported");
- break;
- case 'U':
- encoding = UTF8_e;
- break;
- case 'X':
- break;
- default:
- gcc_unreachable();
- }
- assert(encoding <= iconv_YU_e);
- return *this;
- }
+ literal_t& set_prefix( const char *input, size_t len );
+
bool
compatible_prefix( const literal_t& that ) const {
if( prefix[0] != that.prefix[0] ) {
@@ -456,7 +452,7 @@
CF CH
CHANGED CHAR CHAR_NATIONAL "CHAR-NATIONAL"
CHARACTER CHARACTERS CHECKING CLASS
- COBOL CODE CODESET COLLATING
+ COBOL CODE CODESET "CODE-SET" COLLATING
COLUMN COMBINED_DATETIME "COMBINED-DATETIME"
COMMA COMMAND_LINE "COMMAND-LINE"
COMMAND_LINE_COUNT "COMMAND-LINE-COUNT"
@@ -524,7 +520,7 @@
INTEGER_OF_DAY "INTEGER-OF-DAY"
INTEGER_OF_FORMATTED_DATE "INTEGER-OF-FORMATTED-DATE"
INTEGER_PART "INTEGER-PART"
- INTO INTRINSIC INVOKE IO IO_CONTROL "IO-CONTROL"
+ INTO INTRINSIC INVOKE IO "I-O" IO_CONTROL "I-O-CONTROL"
IS ISNT "IS NOT"
KANJI KEY
@@ -600,7 +596,7 @@
STATUS STRONG
SUBSTITUTE SUM SYMBOL SYMBOLIC SYNCHRONIZED
- TALLY TALLYING TAN TERMINATE TEST
+ TALLYING TAN TERMINATE TEST
TEST_DATE_YYYYMMDD "TEST-DATE-YYYYMMDD"
TEST_DAY_YYYYDDD "TEST-DAY-YYYYDDD"
TEST_FORMATTED_DATETIME "TEST-FORMATTED-DATETIME"
@@ -663,6 +659,8 @@
UNDERLINE UNSIGNED_kw
UTF_16 "UTF-16"
UTF_8 "UTF-8"
+ XMLGENERATE "XML GENERATE"
+ XMLPARSE "XML PARSE"
ADDRESS
END_ACCEPT "END-ACCEPT"
@@ -814,6 +812,7 @@
%type <error> on_overflow on_overflows
%type <error> arith_err arith_errs
%type <error> accept_except accept_excepts call_except call_excepts
+
%type <compute_body_t> compute_body
%type <refer> ffi_name set_operand set_tgt scalar_arg unstring_src
@@ -837,6 +836,12 @@
%type <number> mistake globally first_last
%type <io_mode> io_mode
+%type <label_pair> xmlprocs
+%type <error> xmlexcept xmlexcepts
+%type <field> xmlencoding xmlvalidating
+%type <number> xmlreturning
+%type <label> xmlparse_body
+
%type <labels> labels
%type <label> label_1 section_name
@@ -868,6 +873,8 @@
%type <opt_init_sects> opt_init_sects
%type <opt_init_sect> opt_init_sect
%type <number> opt_init_value
+%type <number> locale_current loc_category user_default
+%type <token_list> loc_categories locale_tgt
%type <opt_round> rounded round_between rounded_type rounded_mode
%type <opt_arith> opt_arith_type
%type <module_type> module_type
@@ -944,7 +951,9 @@
struct { cbl_refer_t *input, *delimiter; } delimited_1;
struct { cbl_refer_t *from, *len; } refmod_parts;
struct refer_collection_t *delimiteds;
+
struct { cbl_label_t *on_error, *not_error; } error;
+ label_pair_t label_pair;
struct { unsigned int nclause; bool tf; } error_clauses;
struct refer_pair_t { cbl_refer_t *first, *second; } refer2;
struct { refer_collection_t *inputs; refer_pair_t into; } str_body;
@@ -977,6 +986,7 @@
substitution_t substitution;
substitutions_t *substitutions;
struct { bool is_locale; cbl_refer_t *arg2; } numval_locale_t;
+ locale_tgt_t *token_list;
cbl_options_t::arith_t opt_arith;
cbl_round_t opt_round;
@@ -1064,8 +1074,7 @@
SEARCH SET SELECT SORT SORT_MERGE
STRING_kw STOP SUBTRACT START
UNSTRING WRITE WHEN INVALID
- XMLGENERATE "XML GENERATE"
- XMLPARSE "XML PARSE"
+ XMLGENERATE XMLPARSE
%left ABS ACCESS ACOS ACTUAL ADVANCING AFP_5A AFTER ALL
ALLOCATE
@@ -1241,7 +1250,7 @@
LITERAL SUBSTITUTE SUM SWITCH SYMBOL SYMBOLIC SYNCHRONIZED
SYSIN SYSIPT SYSLST SYSOUT SYSPCH SYSPUNCH
- TALLY TALLYING TAN TERMINATE TEST
+ TALLYING TAN TERMINATE TEST
TEST_DATE_YYYYMMDD
TEST_DAY_YYYYDDD
TEST_FORMATTED_DATETIME
@@ -1589,8 +1598,8 @@ function_id: FUNCTION NAME program_as program_attrs[attr] '.'
if( !current.new_program(@NAME, LblFunction, $NAME,
$program_as.data,
$attr.common, $attr.initial) ) {
- auto L = symbol_program(current_program_index(), $NAME);
- assert(L);
+ auto e = symbol_function(current_program_index(), $NAME);
+ auto L = cbl_label_of(e);
error_msg(@NAME, "FUNCTION %s already defined on line %d",
$NAME, L->line);
YYERROR;
@@ -2734,9 +2743,18 @@ device_name: SYSIN { $$.token = SYSIN; $$.id = SYSIN_e; }
/* ENVIRONMENT_VALUE { $$.token=0; $$.id = ENV_VALUE_e; } */
;
-alphabet_name: STANDARD_ALPHABET { $$ = alphabet_add(@1, ASCII_e); }
+alphabet_name: STANDARD_ALPHABET { $$ = alphabet_add(@1, CP1252_e); }
| NATIVE { $$ = alphabet_add(@1, EBCDIC_e); }
| EBCDIC { $$ = alphabet_add(@1, EBCDIC_e); }
+ | LOCALE ctx_name
+ {
+ auto e = symbol_alphabet(PROGRAM, $ctx_name);
+ if( !e ) {
+ error_msg(@ctx_name, "no such ALPHABET %qs", $ctx_name);
+ YYERROR;
+ }
+ $$ = cbl_alphabet_of(e);
+ }
| alphabet_seqs
{
$1->reencode();
@@ -4208,16 +4226,17 @@ picture_clause: PIC signed nps[fore] nines nps[aft]
{
cbl_field_t *field = current_field();
field->data.digits = $left + $rdigits;
+ field->attr |= $signed;
if( field->is_binary_integer() ) {
field->data.capacity = type_capacity(field->type,
field->data.digits);
+ field->data.rdigits = $rdigits;
} else {
if( !field_type_update(field, FldNumericDisplay, @$) ) {
YYERROR;
}
ERROR_IF_CAPACITY(@PIC, field);
- field->attr |= $signed;
field->data.capacity = field->data.digits;
field->data.rdigits = $rdigits;
}
@@ -4487,8 +4506,8 @@ usage_clause1: usage BIT
field->clear_attr(signable_e);
} else {
error_msg(@comp, "numeric USAGE invalid "
- "with Alpnanumeric PICTURE");
- dialect_error(@1, "Alpnanumeric COMP-5 or COMP-X", "mf or gnu");
+ "with Alphanumeric PICTURE");
+ dialect_error(@1, "Alphanumeric COMP-5 or COMP-X", "mf or gnu");
YYERROR;
}
break;
@@ -4568,8 +4587,8 @@ usage_clause1: usage BIT
field->clear_attr(signable_e);
} else {
error_msg(@comp, "numeric USAGE invalid "
- "with Alpnanumeric PICTURE");
- dialect_error(@1, "Alpnanumeric COMP-5 or COMP-X", "mf or gnu");
+ "with Alphanumeric PICTURE");
+ dialect_error(@1, "Alphanumeric COMP-5 or COMP-X", "mf or gnu");
YYERROR;
}
break;
@@ -7341,8 +7360,7 @@ num_value: scalar // might actually be a string
| DETAIL OF scalar {$$ = $scalar; }
| LENGTH_OF binary_type[size] {
location_set(@1);
- $$ = new cbl_refer_t( new_tempnumeric() );
- $$->field->clear_attr(signable_e);
+ $$ = new cbl_refer_t( new_tempnumeric(none_e) );
if( dialect_gcc() ) {
dialect_error(@1, "LENGTH OF", "ibm");
}
@@ -7350,8 +7368,7 @@ num_value: scalar // might actually be a string
}
| LENGTH_OF name[val] {
location_set(@1);
- $$ = new cbl_refer_t( new_tempnumeric() );
- $$->field->clear_attr(signable_e);
+ $$ = new cbl_refer_t( new_tempnumeric(none_e) );
if( dialect_gcc() ) {
dialect_error(@1, "LENGTH OF", "ibm");
}
@@ -7359,8 +7376,7 @@ num_value: scalar // might actually be a string
}
| LENGTH_OF name[val] subscripts[subs] {
location_set(@1);
- $$ = new cbl_refer_t( new_tempnumeric() );
- $$->field->clear_attr(signable_e);
+ $$ = new cbl_refer_t( new_tempnumeric(none_e) );
if( dialect_gcc() ) {
dialect_error(@1, "LENGTH OF", "ibm");
}
@@ -7576,8 +7592,7 @@ signed_literal: num_literal
}
| LENGTH_OF binary_type[size] {
location_set(@1);
- $$ = new_tempnumeric();
- $$->clear_attr(signable_e);
+ $$ = new_tempnumeric(none_e);
if( dialect_gcc() ) {
dialect_error(@1, "LENGTH OF", "ibm");
}
@@ -7585,8 +7600,7 @@ signed_literal: num_literal
}
| LENGTH_OF name[val] {
location_set(@1);
- $$ = new_tempnumeric();
- $$->clear_attr(signable_e);
+ $$ = new_tempnumeric(none_e);
if( dialect_gcc() ) {
dialect_error(@1, "LENGTH OF", "ibm");
}
@@ -7594,8 +7608,7 @@ signed_literal: num_literal
}
| LENGTH_OF name[val] subscripts[subs] {
location_set(@1);
- $$ = new_tempnumeric();
- $$->clear_attr(signable_e);
+ $$ = new_tempnumeric(none_e);
if( dialect_gcc() ) {
dialect_error(@1, "LENGTH OF", "ibm");
}
@@ -8146,8 +8159,7 @@ varg1a: ADDRESS OF scalar {
}
| LENGTH_OF binary_type[size] {
location_set(@1);
- $$ = new cbl_refer_t( new_tempnumeric() );
- $$->field->clear_attr(signable_e);
+ $$ = new cbl_refer_t( new_tempnumeric(none_e) );
if( dialect_gcc() ) {
dialect_error(@1, "LENGTH OF", "ibm");
}
@@ -8155,8 +8167,7 @@ varg1a: ADDRESS OF scalar {
}
| LENGTH_OF name[val] {
location_set(@1);
- $$ = new cbl_refer_t( new_tempnumeric() );
- $$->field->clear_attr(signable_e);
+ $$ = new cbl_refer_t( new_tempnumeric(none_e) );
if( dialect_gcc() ) {
dialect_error(@1, "LENGTH OF", "ibm");
}
@@ -8164,8 +8175,7 @@ varg1a: ADDRESS OF scalar {
}
| LENGTH_OF name[val] subscripts[subs] {
location_set(@1);
- $$ = new cbl_refer_t( new_tempnumeric() );
- $$->field->clear_attr(signable_e);
+ $$ = new cbl_refer_t( new_tempnumeric(none_e) );
if( dialect_gcc() ) {
dialect_error(@1, "LENGTH OF", "ibm");
}
@@ -8881,6 +8891,23 @@ set: SET set_tgts[tgts] TO set_operand[src]
new_literal($src, quoted_e);
ast_set_pointers($tgts->targets, literal);
}
+ // Format 12 (save-locale):
+ | SET set_tgts[tgts] TO LOCALE locale_current
+ {
+ if( $tgts->targets.size() > 1 ) {
+ error_msg(@tgts, "only 1 save-locale data-item is valid");
+ }
+ switch($locale_current) {
+ case LC_ALL_kw:
+ case DEFAULT:
+ ast_save_locale($tgts->targets.front().refer, $locale_current);
+ break;
+ default:
+ gcc_unreachable();
+ }
+ cbl_unimplementedw("unimplemented: SET TO LOCALE");
+ }
+ ;
| SET set_tgts[tgts] UP BY num_operand[src]
{
statement_begin(@1, SET);
@@ -8939,6 +8966,42 @@ set: SET set_tgts[tgts] TO set_operand[src]
set_conditional($yn));
}
| SET { statement_begin(@1, SET); } many_switches
+
+ // Format 11 (set-locale):
+ | SET LOCALE locale_tgt[tgt] TO locale_src
+ {
+ if( $tgt->is_default() ) {
+ // do something $tgt->default_of()
+ } else {
+ // do something $tgt->lc_categories()
+ }
+ cbl_unimplementedw("unimplemented: SET LOCALE");
+ }
+ ;
+
+locale_tgt: user_default { $$ = new locale_tgt_t(); *$$ = $1; }
+ | loc_categories
+ ;
+loc_categories: loc_category { $$ = new locale_tgt_t($1); }
+ | loc_categories loc_category {
+ $$ = $1;
+ $$->push_back($2);
+ }
+ ;
+loc_category: LC_ALL_kw { $$ = LC_ALL_kw; }
+ | LC_COLLATE_kw { $$ = LC_COLLATE_kw; }
+ | LC_CTYPE_kw { $$ = LC_CTYPE_kw; }
+ | LC_MESSAGES_kw { $$ = LC_MESSAGES_kw; }
+ | LC_MONETARY_kw { $$ = LC_MONETARY_kw; }
+ | LC_NUMERIC_kw { $$ = LC_NUMERIC_kw; }
+ | LC_TIME_kw { $$ = LC_TIME_kw; }
+ ;
+locale_src: scalar
+ | DEFAULT { assert($1 == 'U' || $1 == 'S'); }
+ ;
+
+locale_current: LC_ALL_kw { $$ = LC_ALL_kw; } // locale to be saved by SET Format 12.
+ | user_default { $$ = DEFAULT; }
;
many_switches: set_switches
@@ -9273,16 +9336,20 @@ sort_target: label_name
release: RELEASE NAME[record] FROM scalar[name]
{
- statement_begin(@1, RELEASE);
- symbol_elem_t *record = symbol_find(@record, $record);
- parser_move(cbl_field_of(record), *$name);
- parser_release(cbl_field_of(record));
+ if( ! mode_syntax_only() ) {
+ statement_begin(@1, RELEASE);
+ symbol_elem_t *record = symbol_find(@record, $record);
+ parser_move(cbl_field_of(record), *$name);
+ parser_release(cbl_field_of(record));
+ }
}
| RELEASE NAME[record]
{
- statement_begin(@1, RELEASE);
- symbol_elem_t *record = symbol_find(@record, $record);
- parser_release(cbl_field_of(record));
+ if( ! mode_syntax_only() ) {
+ statement_begin(@1, RELEASE);
+ symbol_elem_t *record = symbol_find(@record, $record);
+ parser_release(cbl_field_of(record));
+ }
}
;
@@ -10705,15 +10772,13 @@ intrinsic: function_udf
}
| LENGTH '(' tableish[val] ')' {
location_set(@1);
- $$ = new_tempnumeric("LENGTH");
- $$->clear_attr(signable_e);
+ $$ = new_tempnumeric("LENGTH", none_e);
parser_set_numeric($$, $val->field->size());
if( ! intrinsic_call_1($$, LENGTH, $val, @val)) YYERROR;
}
| LENGTH '(' varg1a[val] ')' {
location_set(@1);
- $$ = new_tempnumeric("LENGTH");
- $$->clear_attr(signable_e);
+ $$ = new_tempnumeric("LENGTH", none_e);
parser_set_numeric($$, $val->field->data.capacity);
if( ! intrinsic_call_1($$, LENGTH, $val, @val)) YYERROR;
}
@@ -10738,7 +10803,7 @@ intrinsic: function_udf
| ORD '(' alpha_val[r1] ')'
{
location_set(@1);
- $$ = new_tempnumeric("ORD");
+ $$ = new_tempnumeric("ORD", none_e);
if( ! intrinsic_call_1($$, ORD, $r1, @r1)) YYERROR;
}
| RANDOM
@@ -11436,6 +11501,20 @@ usage: %empty
| USAGE IS
;
+user_default: DEFAULT
+ { // cannot be empty
+ switch( $1 ) {
+ case 'U': break;
+ case 'S':
+ error_msg(@1, "invalid syntax: SYSTEM-DEFAULT");
+ break;
+ default:
+ error_msg(@1, "invalid syntax: DEFAULT");
+ gcc_unreachable();
+ }
+ }
+ ;
+
with: %empty
| WITH
;
@@ -11689,40 +11768,115 @@ xml_generic_numeric:
;
xmlparse: xmlparse_impl end_xml {
- cbl_unimplemented("XML PARSE");
+ auto xml_stmt = xml_statements.top();
+ parser_xml_end(xml_stmt);
+ xml_statements.pop();
+ current.declaratives_evaluate();
}
| xmlparse_cond end_xml {
- cbl_unimplemented("XML PARSE");
+ auto xml_stmt = xml_statements.top();
+ parser_xml_end(xml_stmt);
+ xml_statements.pop();
+ current.declaratives_evaluate();
}
;
-xmlparse_impl: XMLPARSE xmlparse_body
+xmlparse_impl: XMLPARSE xmlparse_body[body]
+ {
+ parser_xml_on_exception($body);
+ parser_xml_not_exception($body);
+ }
;
xmlparse_cond: XMLPARSE xmlparse_body[body] xmlexcepts[err]
+ {
+ if( ! $err.on_error ) parser_xml_on_exception($body);
+ if( ! $err.not_error ) parser_xml_not_exception($body);
+ }
;
-xmlparse_body: XMLPARSE name xmlencoding xmlreturning xmlvalidating
- PROCESSING PROCEDURE is xmlprocs
+xmlparse_body: scalar xmlencoding xmlreturning xmlvalidating
+ PROCESSING PROCEDURE is xmlprocs[procs]
+ {
+ $$ = label_add(@$, LblXml, uniq_label("xml"));
+ xml_statements.push($$);
+ statement_begin(@$, XMLPARSE);
+ parser_xml_parse( $$,
+ *$scalar,
+ $xmlencoding,
+ $xmlvalidating,
+ $xmlreturning == NATIONAL,
+ $procs.from,
+ $procs.to );
+ }
;
-xmlencoding: %empty %prec NAME
- | with ENCODING name [codepage]
+xmlencoding: %empty %prec NAME { $$ = nullptr; }
+ | with ENCODING name [codepage] { $$ = $codepage; }
;
-xmlreturning: %empty
- | RETURNING NATIONAL
+xmlreturning: %empty { $$ = 0; }
+ | RETURNING NATIONAL { $$ = NATIONAL; }
;
-xmlvalidating: %empty
- | VALIDATING with name
- | VALIDATING with FILE_KW name
+xmlvalidating: %empty { $$ = nullptr; }
+ | VALIDATING with name { $$ = $name; }
+ | VALIDATING with FILE_KW name { $$ = $name; }
;
-xmlprocs: label_1[proc]
- | label_1[proc1] THRU label_1[proc2]
+xmlprocs: label_1 {
+ $$ = label_pair_t{$1};
+ }
+ | label_1[from] THRU label_1[to] {
+ $$ = label_pair_t{$from, $to};
+ }
;
xmlexcepts: xmlexcept[a] statements %prec XMLPARSE
+ {
+ assert( $a.on_error || $a.not_error );
+ assert( ! ($a.on_error && $a.not_error) );
+ $$ = $a;
+ }
| xmlexcepts[a] xmlexcept[b] statements %prec XMLPARSE
- ;
+ {
+ if( $a.on_error && $a.not_error ) {
+ error_msg(@1, "too many ON ERROR clauses");
+ YYERROR;
+ }
+ // "ON" and "NOT ON" could be reversed, but not duplicated.
+ if( $a.on_error && $b.on_error ) {
+ error_msg(@1, "duplicate ON ERROR clauses");
+ YYERROR;
+ }
+ if( $a.not_error && $b.not_error ) {
+ error_msg(@1, "duplicate NOT ON ERROR clauses");
+ YYERROR;
+ }
+ $$ = $a;
+ if( $$.on_error ) {
+ assert($b.not_error);
+ $$.not_error = $b.not_error;
+ } else {
+ assert($b.on_error);
+ $$.on_error = $b.on_error;
+ }
+ }
+ ;
xmlexcept: EXCEPTION
+ {
+ auto xml_stmt = xml_statements.top();
+ // The value of the pointer no longer matters, only NULL or not.
+ $$.on_error = $$.not_error = nullptr;
+ switch($1) {
+ case EXCEPTION:
+ $$.on_error = xml_stmt;
+ parser_xml_on_exception(xml_stmt);
+ break;
+ case NOT:
+ $$.not_error = xml_stmt;
+ parser_xml_not_exception(xml_stmt);
+ break;
+ default:
+ gcc_unreachable();
+ }
+ }
;
end_xml: %empty %prec XMLPARSE
@@ -11864,12 +12018,6 @@ bool iso_cobol_word( const std::string& name, bool include_context );
* REPOSITORY names.
*/
-// tokens.h is generated as needed from parse.h with tokens.h.gen
-current_tokens_t::tokenset_t::tokenset_t() {
-#include "token_names.h"
-}
-
-
// Look up the lowercase form of a keyword, excluding some CDF names.
int
current_tokens_t::tokenset_t::find( const cbl_name_t name, bool include_intrinsics ) {
@@ -13391,6 +13539,54 @@ cbl_figconst_field_of( const char *value ) {
return token == 0 ? nullptr : constant_of(constant_index(token));
}
+const char *
+literal_t::symbol_name() const {
+ return isym? cbl_field_of(symbol_at(isym))->name : "";
+}
+
+literal_t&
+literal_t::set( const cbl_field_t * field ) {
+ assert(field->has_attr(constant_e));
+ assert(is_literal(field));
+
+ set_prefix( "", 0 );
+ set_data( field->data.capacity,
+ const_cast<char*>(field->data.initial),
+ field_index(field) );
+ return *this;
+}
+
+literal_t&
+literal_t::set_prefix( const char *input, size_t len ) {
+ encoding = current_encoding('A');
+ assert(len < sizeof(prefix));
+ std::fill(prefix, prefix + sizeof(prefix), '\0');
+ std::transform(input, input + len, prefix, toupper);
+ switch(prefix[0]) {
+ case '\0': case 'Z':
+ encoding = current_encoding('A');
+ break;
+ case 'N':
+ encoding = current_encoding('N');
+ if( 'X' == prefix[1] ) {
+ cbl_unimplemented("NX literals");
+ }
+ break;
+ case 'G':
+ cbl_unimplemented("DBCS encoding not supported");
+ break;
+ case 'U':
+ encoding = UTF8_e;
+ break;
+ case 'X':
+ break;
+ default:
+ gcc_unreachable();
+ }
+ assert(encoding <= iconv_YU_e);
+ return *this;
+}
+
cbl_field_attr_t
literal_attr( const char prefix[] ) {
@@ -13766,3 +13962,4 @@ eval_subject_t::compare( const cbl_refer_t& object,
parser_relop(result, subject, eq_op, object);
return result;
}
+