[PATCH v2 3/6] dtc: Turn 'uint64_t integer' into a struct

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



This allows adding support for signed operations and preserving negative
integers in yaml and dts output.

Signed-off-by: Andrei Ziureaev <andrei.ziureaev@xxxxxxx>
---
 dtc-lexer.l  |  10 ++--
 dtc-parser.y | 127 +++++++++++++++++++++++++++++++++++++--------------
 dtc.h        |   3 ++
 3 files changed, 102 insertions(+), 38 deletions(-)

diff --git a/dtc-lexer.l b/dtc-lexer.l
index b3b7270..037a2ab 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -156,7 +156,9 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
 			DPRINT("Integer Literal: '%s'\n", yytext);
 
 			errno = 0;
-			yylval.integer = strtoull(yytext, &e, 0);
+			yylval.integer = (struct integer){
+				strtoull(yytext, &e, 0)
+			};
 
 			if (*e && e[strspn(e, "UL")]) {
 				lexical_error("Bad integer literal '%s'",
@@ -180,9 +182,11 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
 			d = data_copy_escape_string(yytext+1, yyleng-2);
 			if (d.len == 1) {
 				lexical_error("Empty character literal");
-				yylval.integer = 0;
+				yylval.integer = (struct integer){ 0 };
 			} else {
-				yylval.integer = (unsigned char)d.val[0];
+				yylval.integer = (struct integer){
+					(unsigned char)d.val[0]
+				};
 
 				if (d.len > 2)
 					lexical_error("Character literal has %d"
diff --git a/dtc-parser.y b/dtc-parser.y
index c8c1875..3bc1aca 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -41,7 +41,7 @@ extern bool treesource_error;
 	struct node *node;
 	struct node *nodelist;
 	struct reserve_info *re;
-	uint64_t integer;
+	struct integer integer;
 	unsigned int flags;
 }
 
@@ -140,7 +140,7 @@ memreserves:
 memreserve:
 	  DT_MEMRESERVE integer_prim integer_prim ';'
 		{
-			$$ = build_reserve_entry($2, $3);
+			$$ = build_reserve_entry($2.ull, $3.ull);
 		}
 	| DT_LABEL memreserve
 		{
@@ -310,13 +310,13 @@ propdata:
 			FILE *f = srcfile_relative_open($4.val, NULL);
 			struct data d;
 
-			if ($6 != 0)
-				if (fseek(f, $6, SEEK_SET) != 0)
+			if ($6.ull != 0)
+				if (fseek(f, $6.ull, SEEK_SET) != 0)
 					die("Couldn't seek to offset %llu in \"%s\": %s",
-					    (unsigned long long)$6, $4.val,
+					    (unsigned long long)$6.ull, $4.val,
 					    strerror(errno));
 
-			d = data_copy_file(f, $8);
+			d = data_copy_file(f, $8.ull);
 
 			$$ = data_merge($1, d);
 			fclose(f);
@@ -358,7 +358,7 @@ arrayprefix:
 			unsigned long long bits;
 			enum markertype type = TYPE_UINT32;
 
-			bits = $2;
+			bits = $2.ull;
 
 			switch (bits) {
 			case 8: type = TYPE_UINT8; break;
@@ -391,12 +391,12 @@ arrayprefix:
 				 * within the mask to one (i.e. | in the
 				 * mask), all bits are one.
 				 */
-				if (($2 > mask) && (($2 | mask) != -1ULL))
+				if (($2.ull > mask) && (($2.ull | mask) != -1ULL))
 					ERROR(&@2, "Value out of range for"
 					      " %d-bit array element", $1.bits);
 			}
 
-			$$.data = data_append_integer($1.data, $2, $1.bits);
+			$$.data = data_append_integer($1.data, $2.ull, $1.bits);
 		}
 	| arrayprefix dt_ref
 		{
@@ -433,78 +433,126 @@ integer_expr:
 
 integer_trinary:
 	  integer_or
-	| integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; }
+	| integer_or '?' integer_expr ':' integer_trinary { $$ = $1.ull ? $3 : $5; }
 	;
 
 integer_or:
 	  integer_and
-	| integer_or DT_OR integer_and { $$ = $1 || $3; }
+	| integer_or DT_OR integer_and
+		{
+			$$ = (struct integer){ $1.ull || $3.ull };
+		}
 	;
 
 integer_and:
 	  integer_bitor
-	| integer_and DT_AND integer_bitor { $$ = $1 && $3; }
+	| integer_and DT_AND integer_bitor
+		{
+			$$ = (struct integer){ $1.ull && $3.ull };
+		}
 	;
 
 integer_bitor:
 	  integer_bitxor
-	| integer_bitor '|' integer_bitxor { $$ = $1 | $3; }
+	| integer_bitor '|' integer_bitxor
+		{
+			$$ = (struct integer){ $1.ull | $3.ull };
+		}
 	;
 
 integer_bitxor:
 	  integer_bitand
-	| integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; }
+	| integer_bitxor '^' integer_bitand
+		{
+			$$ = (struct integer){ $1.ull ^ $3.ull };
+		}
 	;
 
 integer_bitand:
 	  integer_eq
-	| integer_bitand '&' integer_eq { $$ = $1 & $3; }
+	| integer_bitand '&' integer_eq
+		{
+			$$ = (struct integer){ $1.ull & $3.ull };
+		}
 	;
 
 integer_eq:
 	  integer_rela
-	| integer_eq DT_EQ integer_rela { $$ = $1 == $3; }
-	| integer_eq DT_NE integer_rela { $$ = $1 != $3; }
+	| integer_eq DT_EQ integer_rela
+		{
+			$$ = (struct integer){ $1.ull == $3.ull };
+		}
+	| integer_eq DT_NE integer_rela
+		{
+			$$ = (struct integer){ $1.ull != $3.ull };
+		}
 	;
 
 integer_rela:
 	  integer_shift
-	| integer_rela '<' integer_shift { $$ = $1 < $3; }
-	| integer_rela '>' integer_shift { $$ = $1 > $3; }
-	| integer_rela DT_LE integer_shift { $$ = $1 <= $3; }
-	| integer_rela DT_GE integer_shift { $$ = $1 >= $3; }
+	| integer_rela '<' integer_shift
+		{
+			$$ = (struct integer){ $1.ull < $3.ull };
+		}
+	| integer_rela '>' integer_shift
+		{
+			$$ = (struct integer){ $1.ull > $3.ull };
+		}
+	| integer_rela DT_LE integer_shift
+		{
+			$$ = (struct integer){ $1.ull <= $3.ull };
+		}
+	| integer_rela DT_GE integer_shift
+		{
+			$$ = (struct integer){ $1.ull >= $3.ull };
+		}
 	;
 
 integer_shift:
-	  integer_shift DT_LSHIFT integer_add { $$ = ($3 < 64) ? ($1 << $3) : 0; }
-	| integer_shift DT_RSHIFT integer_add { $$ = ($3 < 64) ? ($1 >> $3) : 0; }
+	  integer_shift DT_LSHIFT integer_add
+		{
+			$$ = (struct integer){ ($3.ull < 64) ? ($1.ull << $3.ull) : 0 };
+		}
+	| integer_shift DT_RSHIFT integer_add
+		{
+			$$ = (struct integer){ ($3.ull < 64) ? ($1.ull >> $3.ull) : 0 };
+		}
 	| integer_add
 	;
 
 integer_add:
-	  integer_add '+' integer_mul { $$ = $1 + $3; }
-	| integer_add '-' integer_mul { $$ = $1 - $3; }
+	  integer_add '+' integer_mul
+		{
+			$$ = (struct integer){ $1.ull + $3.ull };
+		}
+	| integer_add '-' integer_mul
+		{
+			$$ = (struct integer){ $1.ull - $3.ull };
+		}
 	| integer_mul
 	;
 
 integer_mul:
-	  integer_mul '*' integer_unary { $$ = $1 * $3; }
+	  integer_mul '*' integer_unary
+		{
+			$$ = (struct integer){ $1.ull * $3.ull };
+		}
 	| integer_mul '/' integer_unary
 		{
-			if ($3 != 0) {
-				$$ = $1 / $3;
+			if ($3.ull != 0) {
+				$$ = (struct integer){ $1.ull / $3.ull };
 			} else {
 				ERROR(&@$, "Division by zero");
-				$$ = 0;
+				$$ = (struct integer){ 0 };
 			}
 		}
 	| integer_mul '%' integer_unary
 		{
-			if ($3 != 0) {
-				$$ = $1 % $3;
+			if ($3.ull != 0) {
+			$$ = (struct integer){ $1.ull % $3.ull };
 			} else {
 				ERROR(&@$, "Division by zero");
-				$$ = 0;
+				$$ = (struct integer){ 0 };
 			}
 		}
 	| integer_unary
@@ -512,9 +560,18 @@ integer_mul:
 
 integer_unary:
 	  integer_prim
-	| '-' integer_unary { $$ = -$2; }
-	| '~' integer_unary { $$ = ~$2; }
-	| '!' integer_unary { $$ = !$2; }
+	| '-' integer_unary
+		{
+			$$ = (struct integer){ -$2.ull };
+		}
+	| '~' integer_unary
+		{
+			$$ = (struct integer){ ~$2.ull };
+		}
+	| '!' integer_unary
+		{
+			$$ = (struct integer){ !$2.ull };
+		}
 	;
 
 bytestring:
diff --git a/dtc.h b/dtc.h
index e3225ab..ccfe689 100644
--- a/dtc.h
+++ b/dtc.h
@@ -117,6 +117,9 @@ struct data {
 	struct marker *markers;
 };
 
+struct integer {
+	uint64_t ull;
+};
 
 #define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ })
 
-- 
2.17.1




[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux