Skip to content

Commit

Permalink
Fix enum error when value contains char in compound expression
Browse files Browse the repository at this point in the history
Problem: When enum value contains compound expression with a char
constant, the quotes around char constant is missing in the generated
expression. Example:

enum media_type {
  YUY2 = ((('2' << 24) | ('Y' << 16)) | ('U' << 8)) | 'Y'
};

The generated C# enum becomes:

public enum media_type {
  YUY2 = (((2 << 24)|(Y << 16))|(U << 8))|Y
}

While the correct representation (after this fix) should be:

public enum media_type {
  YUY2 = ((('2' << 24)|('Y' << 16))|('U' << 8))|'Y'
}

Causes: the exprcompound promotes the expression type from char to int
and uses $1.val in the generated expression. However $1.val does not
contain the quotes. Since the type is promoted to int, there's no way to
know there's char component in the compound expression.

Solution: in exprcomound, use $1.rawval if $1.type is T_CHAR or T_WCHAR.
The rawval contains quotes which yield correct expression.
  • Loading branch information
jiulongw committed Sep 7, 2016
1 parent c252d5c commit e1afb6f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 20 deletions.
3 changes: 3 additions & 0 deletions Source/CParse/cparse.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,7 @@ extern "C" {
#define SWIG_WARN_NODE_END(Node) \
if (wrnfilter) Swig_warnfilter(wrnfilter,0); \
}

#define COMPOUND_EXPR_VAL(dtype) \
((dtype).type == T_CHAR || (dtype).type == T_WCHAR ? (dtype).rawval : (dtype).val)
#endif
40 changes: 20 additions & 20 deletions Source/CParse/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -6095,81 +6095,81 @@ exprnum : NUM_INT { $$ = $1; }
;

exprcompound : expr PLUS expr {
$$.val = NewStringf("%s+%s",$1.val,$3.val);
$$.val = NewStringf("%s+%s", COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type);
}
| expr MINUS expr {
$$.val = NewStringf("%s-%s",$1.val,$3.val);
$$.val = NewStringf("%s-%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type);
}
| expr STAR expr {
$$.val = NewStringf("%s*%s",$1.val,$3.val);
$$.val = NewStringf("%s*%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type);
}
| expr SLASH expr {
$$.val = NewStringf("%s/%s",$1.val,$3.val);
$$.val = NewStringf("%s/%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type);
}
| expr MODULO expr {
$$.val = NewStringf("%s%%%s",$1.val,$3.val);
$$.val = NewStringf("%s%%%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type);
}
| expr AND expr {
$$.val = NewStringf("%s&%s",$1.val,$3.val);
$$.val = NewStringf("%s&%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type);
}
| expr OR expr {
$$.val = NewStringf("%s|%s",$1.val,$3.val);
$$.val = NewStringf("%s|%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type);
}
| expr XOR expr {
$$.val = NewStringf("%s^%s",$1.val,$3.val);
$$.val = NewStringf("%s^%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote($1.type,$3.type);
}
| expr LSHIFT expr {
$$.val = NewStringf("%s << %s",$1.val,$3.val);
$$.val = NewStringf("%s << %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote_type($1.type);
}
| expr RSHIFT expr {
$$.val = NewStringf("%s >> %s",$1.val,$3.val);
$$.val = NewStringf("%s >> %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = promote_type($1.type);
}
| expr LAND expr {
$$.val = NewStringf("%s&&%s",$1.val,$3.val);
$$.val = NewStringf("%s&&%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr LOR expr {
$$.val = NewStringf("%s||%s",$1.val,$3.val);
$$.val = NewStringf("%s||%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr EQUALTO expr {
$$.val = NewStringf("%s==%s",$1.val,$3.val);
$$.val = NewStringf("%s==%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr NOTEQUALTO expr {
$$.val = NewStringf("%s!=%s",$1.val,$3.val);
$$.val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
/* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these.
| expr GREATERTHAN expr {
$$.val = NewStringf("%s > %s", $1.val, $3.val);
$$.val = NewStringf("%s > %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr LESSTHAN expr {
$$.val = NewStringf("%s < %s", $1.val, $3.val);
$$.val = NewStringf("%s < %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
*/
| expr GREATERTHANOREQUALTO expr {
$$.val = NewStringf("%s >= %s", $1.val, $3.val);
$$.val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr LESSTHANOREQUALTO expr {
$$.val = NewStringf("%s <= %s", $1.val, $3.val);
$$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
$$.val = NewStringf("%s?%s:%s", $1.val, $3.val, $5.val);
$$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3), COMPOUND_EXPR_VAL($5));
/* This may not be exactly right, but is probably good enough
* for the purposes of parsing constant expressions. */
$$.type = promote($3.type, $5.type);
Expand All @@ -6187,7 +6187,7 @@ exprcompound : expr PLUS expr {
$$.type = $2.type;
}
| LNOT expr {
$$.val = NewStringf("!%s",$2.val);
$$.val = NewStringf("!%s",COMPOUND_EXPR_VAL($2));
$$.type = T_INT;
}
| type LPAREN {
Expand Down

0 comments on commit e1afb6f

Please sign in to comment.