Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
bbe99022
Commit
bbe99022
authored
May 29, 2003
by
Michael Meskes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Parse forward definiton of structs.
parent
9e2a980f
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
163 additions
and
139 deletions
+163
-139
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/ChangeLog
+4
-0
src/interfaces/ecpg/preproc/pgc.l
src/interfaces/ecpg/preproc/pgc.l
+3
-91
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/preproc.y
+75
-28
src/interfaces/ecpg/preproc/type.c
src/interfaces/ecpg/preproc/type.c
+8
-3
src/interfaces/ecpg/preproc/type.h
src/interfaces/ecpg/preproc/type.h
+6
-0
src/interfaces/ecpg/preproc/variable.c
src/interfaces/ecpg/preproc/variable.c
+67
-17
No files found.
src/interfaces/ecpg/ChangeLog
View file @
bbe99022
...
@@ -1449,6 +1449,10 @@ Tue May 27 13:29:28 CEST 2003
...
@@ -1449,6 +1449,10 @@ Tue May 27 13:29:28 CEST 2003
Tue May 27 16:33:36 CEST 2003
Tue May 27 16:33:36 CEST 2003
- Accept stdin/stdout as input/output file.
- Accept stdin/stdout as input/output file.
Thu May 29 13:58:25 CEST 2003
- ecpg should now be able to parse forward struct definition.
- Set ecpg version to 2.12.0.
- Set ecpg version to 2.12.0.
- Set ecpg library to 3.4.2.
- Set ecpg library to 3.4.2.
- Set pgtypes library to 1.0.0
- Set pgtypes library to 1.0.0
...
...
src/interfaces/ecpg/preproc/pgc.l
View file @
bbe99022
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.11
1 2003/05/27 14:36:00
meskes Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.11
2 2003/05/29 12:00:21
meskes Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -184,6 +184,7 @@ letter_or_digit [\200-\377_A-Za-z0-9]
...
@@ -184,6 +184,7 @@ letter_or_digit [\200-\377_A-Za-z0-9]
identifier {letter}{letter_or_digit}*
identifier {letter}{letter_or_digit}*
array ({letter_or_digit}|[\+\-\*\%\/\(\)])*
typecast "::"
typecast "::"
/*
/*
...
@@ -949,96 +950,7 @@ cppline {space}*#(.*\\{space})+.*
...
@@ -949,96 +950,7 @@ cppline {space}*#(.*\\{space})+.*
<incl>\<[^\>]+\>{space}*";"? { parse_include(); }
<incl>\<[^\>]+\>{space}*";"? { parse_include(); }
<incl>{dquote}{xdinside}{dquote}{space}*";"? { parse_include(); }
<incl>{dquote}{xdinside}{dquote}{space}*";"? { parse_include(); }
<incl>[^;\<\>\"]+";" {
<incl>[^;\<\>\"]+";" { parse_include(); }
parse_include();
#if 0
/* got the include file name */
struct _yy_buffer *yb;
struct _include_path *ip;
char inc_file[MAXPGPATH];
unsigned int i;
yb = mm_alloc(sizeof(struct _yy_buffer));
yb->buffer = YY_CURRENT_BUFFER;
yb->lineno = yylineno;
yb->filename = input_filename;
yb->next = yy_buffer;
yy_buffer = yb;
/*
* skip the ";" and trailing whitespace. Note that yytext contains
* at least one non-space character plus the ";"
*/
for ( i = strlen(yytext)-2;
i > 0 && isspace((unsigned char) yytext[i]);
i-- )
{}
yytext[i+1] = '\0';
yyin = NULL;
/* If file name is enclosed in '"' remove these and look only in '.' */
/* Informix does look into all include paths though, except filename starts with '/' */
if ((yytext[0] == '"' && yytext[i] == '"') && (compat != ECPG_COMPAT_INFORMIX || yytext[0] == '/'))
{
yytext[i] = '\0';
memmove(yytext, yytext+1, strlen(yytext));
strncpy(inc_file, yytext, sizeof(inc_file));
yyin = fopen(inc_file, "r");
if (!yyin)
{
if (strcmp(inc_file + strlen(inc_file) - 2, ".h"))
{
strcat(inc_file, ".h");
yyin = fopen(inc_file, "r");
}
}
}
else
{
if (yytext[0] == '"' && yytext[i] == '"')
{
yytext[i] = '\0';
memmove(yytext, yytext+1, strlen(yytext));
}
for (ip = include_paths; yyin == NULL && ip != NULL; ip = ip->next)
{
if (strlen(ip->path) + strlen(yytext) + 3 > MAXPGPATH)
{
fprintf(stderr, "Error: Path %s/%s is too long in line %d, skipping.\n", ip->path, yytext, yylineno);
continue;
}
snprintf (inc_file, sizeof(inc_file), "%s/%s", ip->path, yytext);
yyin = fopen(inc_file, "r");
if (!yyin)
{
if (strcmp(inc_file + strlen(inc_file) - 2, ".h"))
{
strcat(inc_file, ".h");
yyin = fopen( inc_file, "r" );
}
}
}
}
if (!yyin)
{
snprintf(errortext, sizeof(errortext), "Cannot open include file %s in line %d\n", yytext, yylineno);
mmerror(NO_INCLUDE_FILE, ET_FATAL, errortext);
}
input_filename = mm_strdup(inc_file);
yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE ));
yylineno = 1;
output_line_number();
BEGIN C;
#endif
}
<<EOF>> {
<<EOF>> {
if (yy_buffer == NULL) {
if (yy_buffer == NULL) {
...
...
src/interfaces/ecpg/preproc/preproc.y
View file @
bbe99022
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.22
3 2003/05/27 11:31:52
meskes Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.22
4 2003/05/29 12:00:21
meskes Exp $ */
/* Copyright comment */
/* Copyright comment */
%{
%{
...
@@ -27,6 +27,9 @@ struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
...
@@ -27,6 +27,9 @@ struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
/* also store struct type so we can do a sizeof() later */
/* also store struct type so we can do a sizeof() later */
static char *ECPGstruct_sizeof = NULL;
static char *ECPGstruct_sizeof = NULL;
/* for forward declarations we have to store some data as well */
static char *forward_name = NULL;
struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, NULL, {NULL}};
struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, NULL, {NULL}};
struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
...
@@ -196,6 +199,7 @@ create_questionmarks(char *name, bool array)
...
@@ -196,6 +199,7 @@ create_questionmarks(char *name, bool array)
enum ECPGttype type_enum;
enum ECPGttype type_enum;
enum ECPGdtype dtype_enum;
enum ECPGdtype dtype_enum;
struct fetch_desc descriptor;
struct fetch_desc descriptor;
struct su_symbol struct_union;
}
}
/* special embedded SQL token */
/* special embedded SQL token */
...
@@ -440,7 +444,9 @@ create_questionmarks(char *name, bool array)
...
@@ -440,7 +444,9 @@ create_questionmarks(char *name, bool array)
%type <str> reserved_keyword unreserved_keyword ecpg_interval
%type <str> reserved_keyword unreserved_keyword ecpg_interval
%type <str> col_name_keyword func_name_keyword precision opt_scale
%type <str> col_name_keyword func_name_keyword precision opt_scale
%type <str> ECPGTypeName variablelist ECPGColLabelCommon c_variable
%type <str> ECPGTypeName variablelist ECPGColLabelCommon c_variable
%type <str> s_struct_union_symbol inf_val_list inf_col_list
%type <str> inf_val_list inf_col_list
%type <struct_union> s_struct_union_symbol
%type <descriptor> ECPGGetDescriptor
%type <descriptor> ECPGGetDescriptor
...
@@ -4039,7 +4045,6 @@ connection_target: database_name opt_server opt_port
...
@@ -4039,7 +4045,6 @@ connection_target: database_name opt_server opt_port
}
}
| StringConst
| StringConst
{
{
printf("MM: %s\n", $1);
if ($1[0] == '\"')
if ($1[0] == '\"')
$$ = $1;
$$ = $1;
else if (strcmp($1, " ?") == 0) /* variable */
else if (strcmp($1, " ?") == 0) /* variable */
...
@@ -4425,9 +4430,17 @@ single_vt_type: common_type
...
@@ -4425,9 +4430,17 @@ single_vt_type: common_type
| s_struct_union_symbol
| s_struct_union_symbol
{
{
/* this is for named structs/unions */
/* this is for named structs/unions */
char *name = $1;
char *name;
struct typedefs *this = get_typedef(name);
struct typedefs *this;
bool forward = (strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0);
name = cat2_str($1.su, $1.symbol);
/* Do we have a forward definition? */
if (!forward)
{
/* No */
this = get_typedef(name);
$$.type_str = mm_strdup(this->name);
$$.type_str = mm_strdup(this->name);
$$.type_enum = this->type->type_enum;
$$.type_enum = this->type->type_enum;
$$.type_dimension = this->type->type_dimension;
$$.type_dimension = this->type->type_dimension;
...
@@ -4436,6 +4449,16 @@ single_vt_type: common_type
...
@@ -4436,6 +4449,16 @@ single_vt_type: common_type
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
free(name);
free(name);
}
}
else
{
$$.type_str = name;
$$.type_enum = ECPGt_long;
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = make_str("");
struct_member_list[struct_level] = NULL;
}
}
;
;
/*
/*
...
@@ -4761,8 +4784,17 @@ var_type: common_type
...
@@ -4761,8 +4784,17 @@ var_type: common_type
| s_struct_union_symbol
| s_struct_union_symbol
{
{
/* this is for named structs/unions */
/* this is for named structs/unions */
char *name = $1;
char *name;
struct typedefs *this = get_typedef(name);
struct typedefs *this;
bool forward = (strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0);
name = cat2_str($1.su, $1.symbol);
/* Do we have a forward definition? */
if (!forward)
{
/* No */
this = get_typedef(name);
$$.type_str = mm_strdup(this->name);
$$.type_str = mm_strdup(this->name);
$$.type_enum = this->type->type_enum;
$$.type_enum = this->type->type_enum;
$$.type_dimension = this->type->type_dimension;
$$.type_dimension = this->type->type_dimension;
...
@@ -4771,6 +4803,16 @@ var_type: common_type
...
@@ -4771,6 +4803,16 @@ var_type: common_type
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
free(name);
free(name);
}
}
else
{
$$.type_str = name;
$$.type_enum = ECPGt_long;
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = make_str("");
struct_member_list[struct_level] = NULL;
}
}
;
;
enum_type: SQL_ENUM symbol enum_definition
enum_type: SQL_ENUM symbol enum_definition
...
@@ -4789,18 +4831,21 @@ struct_union_type_with_symbol: s_struct_union_symbol
...
@@ -4789,18 +4831,21 @@ struct_union_type_with_symbol: s_struct_union_symbol
struct_member_list[struct_level++] = NULL;
struct_member_list[struct_level++] = NULL;
if (struct_level >= STRUCT_DEPTH)
if (struct_level >= STRUCT_DEPTH)
mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure/union definition");
mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure/union definition");
forward_name = mm_strdup($1.symbol);
}
}
'{' variable_declarations '}'
'{' variable_declarations '}'
{
{
ECPGfree_struct_member(struct_member_list[struct_level]);
ECPGfree_struct_member(struct_member_list[struct_level]);
struct_member_list[struct_level] = NULL;
struct_member_list[struct_level] = NULL;
free(actual_storage[struct_level--]);
free(actual_storage[struct_level--]);
if (strncmp($1, "struct", sizeof("struct")-1) == 0)
if (strncmp($1
.su
, "struct", sizeof("struct")-1) == 0)
$$.type_enum = ECPGt_struct;
$$.type_enum = ECPGt_struct;
else
else
$$.type_enum = ECPGt_union;
$$.type_enum = ECPGt_union;
$$.type_str = mm_strdup($1);
$$.type_str = cat2_str($1.su, $1.symbol);
$$.type_sizeof = cat_str(4, $1, make_str("{"), $4, make_str("}"));
$$.type_sizeof = cat_str(4, mm_strdup($$.type_str), make_str("{"), $4, make_str("}"));
free(forward_name);
forward_name = NULL;
}
}
;
;
...
@@ -4822,12 +4867,14 @@ struct_union_type: struct_union_type_with_symbol { $$ = $1.type_sizeof; }
...
@@ -4822,12 +4867,14 @@ struct_union_type: struct_union_type_with_symbol { $$ = $1.type_sizeof; }
s_struct_union_symbol: SQL_STRUCT symbol
s_struct_union_symbol: SQL_STRUCT symbol
{
{
$$ = cat2_str(make_str("struct"), $2);
$$.su = make_str("struct");
ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), strdup($$), make_str(")"));
$$.symbol = $2;
ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), cat2_str(mm_strdup($$.su), mm_strdup($$.symbol)), make_str(")"));
}
}
| UNION symbol
| UNION symbol
{
{
$$ = cat2_str(make_str("union"), $2);
$$.su = make_str("union");
$$.symbol = $2;
}
}
;
;
...
...
src/interfaces/ecpg/preproc/type.c
View file @
bbe99022
...
@@ -225,7 +225,6 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type,
...
@@ -225,7 +225,6 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type,
case
ECPGt_array
:
case
ECPGt_array
:
if
(
indicator_set
&&
ind_type
->
type
!=
ECPGt_array
)
if
(
indicator_set
&&
ind_type
->
type
!=
ECPGt_array
)
mmerror
(
INDICATOR_NOT_ARRAY
,
ET_FATAL
,
"Indicator for array/pointer has to be array/pointer.
\n
"
);
mmerror
(
INDICATOR_NOT_ARRAY
,
ET_FATAL
,
"Indicator for array/pointer has to be array/pointer.
\n
"
);
switch
(
type
->
u
.
element
->
type
)
switch
(
type
->
u
.
element
->
type
)
{
{
case
ECPGt_array
:
case
ECPGt_array
:
...
@@ -233,8 +232,14 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type,
...
@@ -233,8 +232,14 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type,
break
;
break
;
case
ECPGt_struct
:
case
ECPGt_struct
:
case
ECPGt_union
:
case
ECPGt_union
:
/* If var_array_element is not equal * NULL, we have to use the * <var_array_element>th entry and not * the whole array */
if
(
var_array_element
==
NULL
)
/* If var_array_element is not equal
ECPGdump_a_struct
(
o
,
name
,
ind_name
,
type
->
size
,
* NULL, we have to use the
* <var_array_element>th entry and
* not the whole array */
if
(
var_array_element
==
NULL
)
ECPGdump_a_struct
(
o
,
name
,
ind_name
,
type
->
size
,
type
->
u
.
element
,
type
->
u
.
element
,
(
ind_type
->
type
==
ECPGt_NO_INDICATOR
)
?
ind_type
:
ind_type
->
u
.
element
,
(
ind_type
->
type
==
ECPGt_NO_INDICATOR
)
?
ind_type
:
ind_type
->
u
.
element
,
NULL
,
prefix
,
ind_prefix
);
NULL
,
prefix
,
ind_prefix
);
...
...
src/interfaces/ecpg/preproc/type.h
View file @
bbe99022
...
@@ -88,6 +88,12 @@ struct index
...
@@ -88,6 +88,12 @@ struct index
char
*
str
;
char
*
str
;
};
};
struct
su_symbol
{
char
*
su
;
char
*
symbol
;
};
struct
this_type
struct
this_type
{
{
enum
ECPGttype
type_enum
;
enum
ECPGttype
type_enum
;
...
...
src/interfaces/ecpg/preproc/variable.c
View file @
bbe99022
...
@@ -67,7 +67,7 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
...
@@ -67,7 +67,7 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
}
}
static
struct
variable
*
static
struct
variable
*
find_struct
(
char
*
name
,
char
*
next
)
find_struct
(
char
*
name
,
char
*
next
,
char
*
end
)
{
{
struct
variable
*
p
;
struct
variable
*
p
;
char
c
=
*
next
;
char
c
=
*
next
;
...
@@ -90,13 +90,14 @@ find_struct(char *name, char *next)
...
@@ -90,13 +90,14 @@ find_struct(char *name, char *next)
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
errortext
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
errortext
);
}
}
/* restore the name, we will need it later
on
*/
/* restore the name, we will need it later */
*
next
=
c
;
*
next
=
c
;
next
++
;
return
find_struct_member
(
name
,
next
,
p
->
type
->
u
.
element
->
u
.
members
,
p
->
brace_level
);
return
find_struct_member
(
name
,
end
,
p
->
type
->
u
.
element
->
u
.
members
,
p
->
brace_level
);
}
}
else
else
{
if
(
next
==
end
)
{
{
if
(
p
->
type
->
type
!=
ECPGt_struct
&&
p
->
type
->
type
!=
ECPGt_union
)
if
(
p
->
type
->
type
!=
ECPGt_struct
&&
p
->
type
->
type
!=
ECPGt_union
)
{
{
...
@@ -104,10 +105,30 @@ find_struct(char *name, char *next)
...
@@ -104,10 +105,30 @@ find_struct(char *name, char *next)
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
errortext
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
errortext
);
}
}
/* restore the name, we will need it later on
*/
/* restore the name, we will need it later
*/
*
next
=
c
;
*
next
=
c
;
return
find_struct_member
(
name
,
next
,
p
->
type
->
u
.
members
,
p
->
brace_level
);
return
find_struct_member
(
name
,
end
,
p
->
type
->
u
.
members
,
p
->
brace_level
);
}
else
{
if
(
p
->
type
->
type
!=
ECPGt_array
)
{
snprintf
(
errortext
,
sizeof
(
errortext
),
"variable %s is not an array"
,
name
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
errortext
);
}
if
(
p
->
type
->
u
.
element
->
type
!=
ECPGt_struct
&&
p
->
type
->
u
.
element
->
type
!=
ECPGt_union
)
{
snprintf
(
errortext
,
sizeof
(
errortext
),
"variable %s is not a pointer to a structure or a union"
,
name
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
errortext
);
}
/* restore the name, we will need it later */
*
next
=
c
;
return
find_struct_member
(
name
,
end
,
p
->
type
->
u
.
element
->
u
.
members
,
p
->
brace_level
);
}
}
}
}
}
...
@@ -130,15 +151,43 @@ find_simple(char *name)
...
@@ -130,15 +151,43 @@ find_simple(char *name)
struct
variable
*
struct
variable
*
find_variable
(
char
*
name
)
find_variable
(
char
*
name
)
{
{
char
*
next
;
char
*
next
,
*
end
;
struct
variable
*
p
;
struct
variable
*
p
;
int
count
;
if
((
next
=
strchr
(
name
,
'.'
))
!=
NULL
)
printf
(
"MM: find %s
\n
"
,
name
);
p
=
find_struct
(
name
,
next
);
else
if
((
next
=
strstr
(
name
,
"->"
))
!=
NULL
)
next
=
strpbrk
(
name
,
".[-"
);
p
=
find_struct
(
name
,
next
);
if
(
next
)
{
if
(
*
next
==
'['
)
{
/* We don't care about what's inside the array braces
* so just eat up the character */
for
(
count
=
1
,
end
=
next
+
1
;
count
;
end
++
)
{
switch
(
*
end
)
{
case
'['
:
count
++
;
break
;
case
']'
:
count
--
;
break
;
default
:
break
;
}
}
if
(
*
end
==
'.'
)
p
=
find_struct
(
name
,
next
,
end
);
else
else
{
char
c
=
*
next
;
*
next
=
'\0'
;
p
=
find_simple
(
name
);
p
=
find_simple
(
name
);
*
next
=
c
;
}
}
else
p
=
find_struct
(
name
,
next
,
next
);
}
else
p
=
find_simple
(
name
);
if
(
p
==
NULL
)
if
(
p
==
NULL
)
{
{
...
@@ -330,6 +379,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
...
@@ -330,6 +379,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
errortext
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
errortext
);
/* mmerror(PARSE_ERROR, ET_FATAL, "No multilevel (more than 2) pointer supported %d",pointer_len);*/
/* mmerror(PARSE_ERROR, ET_FATAL, "No multilevel (more than 2) pointer supported %d",pointer_len);*/
}
}
if
(
pointer_len
>
1
&&
type_enum
!=
ECPGt_char
&&
type_enum
!=
ECPGt_unsigned_char
)
if
(
pointer_len
>
1
&&
type_enum
!=
ECPGt_char
&&
type_enum
!=
ECPGt_unsigned_char
)
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No pointer to pointer supported for this type"
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No pointer to pointer supported for this type"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment