diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 62937d4fe6..6225ab2fb6 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3724,3 +3724,6 @@ definition. Contributed by Denis Carikli. * libc/stdlib/lib_rand.c: Always add one to result congruential generators to avoid the value zero. Suggested by Freddie Chopin. + * tools/b16.c: Fixed precision math conversion utility. + * graphics/nxglib/nxglib_splitlinex.c: Fix the "fat, flat line bug" + diff --git a/nuttx/graphics/nxglib/nxglib_splitline.c b/nuttx/graphics/nxglib/nxglib_splitline.c index 11658e1493..fa2ccc1a0d 100644 --- a/nuttx/graphics/nxglib/nxglib_splitline.c +++ b/nuttx/graphics/nxglib/nxglib_splitline.c @@ -1,7 +1,7 @@ /**************************************************************************** * graphics/nxglib/nxglib_splitline.c * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -49,12 +50,16 @@ * Pre-Processor Definitions ****************************************************************************/ -#define SMALL_SIN 1966 /* 1966/65536 = 0.03 */ - /**************************************************************************** * Private Types ****************************************************************************/ +struct b16point_s +{ + b16_t x; + b16_t y; +}; + /**************************************************************************** * Private Data ****************************************************************************/ @@ -67,6 +72,12 @@ * Private Functions ****************************************************************************/ +static b16_t nxgl_interpolate(b16_t x, b16_t dy, b16_t dxdy) +{ + b16_t dx = b16mulb16(dy, dxdy); + return x + dx; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -117,15 +128,19 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, struct nxgl_vector_s line; nxgl_coord_t iheight; nxgl_coord_t iwidth; - nxgl_coord_t iy; - nxgl_coord_t triheight; - nxgl_coord_t halfheight; - b16_t adjwidth; - b16_t xoffset; - b16_t halfoffset; + nxgl_coord_t iyoffset; + struct b16point_s quad[4]; + b16_t b16xoffset; + b16_t b16yoffset; + b16_t b16dxdy; b16_t angle; + b16_t cosangle; b16_t sinangle; b16_t b16x; + b16_t b16y; + + gvdbg("vector: (%d,%d)->(%d,%d) linewidth: %d\n", + vector->pt1.x, vector->pt1.y, vector->pt2.x, vector->pt2.y, linewidth); /* First, check the linewidth */ @@ -153,7 +168,7 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, line.pt2.x = vector->pt1.x; line.pt2.y = vector->pt1.y; } - else + else /* if (vector->pt1.y == vector->pt2.y) */ { /* First degenerate case: The line is horizontal. */ @@ -174,6 +189,10 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, rect->pt1.y = vector->pt1.y - (linewidth >> 1); rect->pt2.y = rect->pt1.y + linewidth - 1; + + gvdbg("Horizontal rect: (%d,%d),(%d,%d)\n", + rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y); + return 2; } @@ -188,6 +207,10 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, rect->pt1.x = line.pt1.x - (linewidth >> 1); rect->pt2.x = rect->pt1.x + linewidth - 1; + + gvdbg("Vertical rect: (%d,%d),(%d,%d)\n", + rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y); + return 2; } @@ -207,6 +230,11 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, traps[1].bot.x1 = itob16(line.pt2.x); traps[1].bot.x2 = traps[1].bot.x1; traps[1].bot.y = line.pt2.y; + + gvdbg("Vertical traps[1]: (%08x,%08x,%d),(%08x,%08x, %d)\n", + traps[1].top.x1, traps[1].top.x2, traps[1].top.y, + traps[1].bot.x1, traps[1].bot.x2, traps[1].bot.y); + return 1; } @@ -226,103 +254,260 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, iwidth = line.pt1.x - line.pt2.x + 1; } - /* Triangle height: linewidth * cosA - * Adjusted width: triheight / sinA - * X offset : linewidth * linewidth / adjusted line width + /* Applying the line width to the line results in a rotated, rectangle. + * Get the Y offset from an end of the original thin line to a corner of the fat line. + * + * Angle of line: angle = atan2(iheight, iwidth) + * Y offset from line: b16yoffset = linewidth * cos(angle) + * + * For near verical lines, b16yoffset is be nearly zero. For near horizontal + * lines, b16yOffset is be about the same as linewidth. */ - angle = b16atan2(itob16(iheight), itob16(iwidth)); - triheight = b16toi(linewidth * b16cos(angle) + b16HALF); - halfheight = (triheight >> 1); + angle = b16atan2(itob16(iheight), itob16(iwidth)); + cosangle = b16cos(angle); + b16yoffset = (linewidth * cosangle + 1) >> 1; - /* If the sine of the angle is tiny (i.e., the line is nearly horizontal), - * then we cannot compute the adjusted width. In this case, just use - * the width of the line bounding box. + /* Get the X offset from an end of the original thin line to a corner of the fat line. + * + * For near vertical lines, b16xoffset is about the same as linewidth. For near + * horizontal lines, b16xoffset is nearly zero. */ - sinangle = b16sin(angle); - if (sinangle < SMALL_SIN) - { - adjwidth = itob16(iwidth); - xoffset = 0; - } - else - { - adjwidth = b16divb16(itob16(linewidth), sinangle); - xoffset = itob16(linewidth * linewidth); - xoffset = b16divb16(xoffset, adjwidth); - } + sinangle = b16sin(angle); + b16xoffset = (linewidth * sinangle + 1) >> 1; - halfoffset = (xoffset >> 1); + gvdbg("height: %d width: %d angle: %08x b16yoffset: %08x b16xoffset: %08x\n", + iheight, iwidth, angle, b16yoffset, b16xoffset); - /* Return the top triangle (if there is one). NOTE that the horizontal - * (z) positions are represented with 16 bits of fraction. The vertical - * (y) positions, on the other hand, are integer. - */ + /* Now we know all four points of the rotated rectangle */ - if (triheight > 0) + iyoffset = b16toi(b16yoffset + b16HALF); + if (iyoffset > 0) { + /* Get the Y positions of each point */ + + b16y = itob16(line.pt1.y); + quad[0].y = b16y - b16yoffset; + quad[1].y = b16y + b16yoffset; + + b16y = itob16(line.pt2.y); + quad[2].y = b16y - b16yoffset; + quad[3].y = b16y + b16yoffset; + if (line.pt1.x < line.pt2.x) { - /* Line is going "south east" */ - - b16x = itob16(line.pt1.x) - halfoffset; - iy = line.pt1.y + halfheight; - - traps[0].top.x1 = b16x + xoffset; - traps[0].top.x2 = traps[0].top.x1; - traps[0].top.y = iy - triheight + 1; - traps[0].bot.x1 = b16x; - traps[0].bot.x2 = b16x + adjwidth - b16ONE; - traps[0].bot.y = iy; - - b16x = itob16(line.pt2.x) + halfoffset; - iy = line.pt2.y - halfheight; - - traps[2].top.x1 = b16x - adjwidth + b16ONE; - traps[2].top.x2 = b16x; - traps[2].top.y = iy; - traps[2].bot.x1 = b16x - xoffset; - traps[2].bot.x2 = traps[2].bot.x1; - traps[2].bot.y = iy + triheight - 1; + /* Line is going "south east". Get the X positions of each point */ + + b16x = itob16(line.pt1.x); + quad[0].x = b16x + b16xoffset; + quad[1].x = b16x - b16xoffset; + + b16x = itob16(line.pt2.x); + quad[2].x = b16x + b16xoffset; + quad[3].x = b16x - b16xoffset; + + gvdbg("Southeast: quad (%08x,%08x),(%08x,%08x),(%08x,%08x),(%08x,%08x)\n", + quad[0].x, quad[0].y, quad[1].x, quad[1].y, + quad[2].x, quad[2].y, quad[3].x, quad[3].y); + + /* Now we can form the trapezoids. The top of the first trapezoid + * (triangle) is at quad[0] + */ + + traps[0].top.x1 = quad[0].x; + traps[0].top.x2 = quad[0].x; + traps[0].top.y = b16toi(quad[0].y + b16HALF); + + /* The bottom of the first trapezoid (triangle) may be either at + * quad[1] or quad[2], depending upon orientation. + */ + + if (quad[1]. y < quad[2].y) + { + /* quad[1] is at the bottom left of the triangle. Interpolate + * to get the corresponding point on the right side. + * + * Interpolation is from quad[0] along the line quad[0]->quad[2] + * which as the same slope as the line (positive) + */ + + b16dxdy = itob16(iwidth) / iheight; + + traps[0].bot.x1 = quad[1].x; + traps[0].bot.x2 = nxgl_interpolate(quad[0].x, quad[1].y - quad[0].y, b16dxdy); + traps[0].bot.y = b16toi(quad[1].y + b16HALF); + + /* quad[1] is at the top left of the second trapezoid. quad[2} is + * at the bottom right of the second trapezoid. Interpolate to get + * corresponding point on the left side. + * + * Interpolation is from quad[1] along the line quad[1]->quad[3] + * which as the same slope as the line (positive) + */ + + traps[1].top.x1 = traps[0].bot.x1; + traps[1].top.x2 = traps[0].bot.x2; + traps[1].top.y = traps[0].bot.y; + + traps[1].bot.x1 = nxgl_interpolate(traps[1].top.x1, quad[2].y - quad[1].y, b16dxdy); + traps[1].bot.x2 = quad[2].x; + traps[1].bot.y = b16toi(quad[2].y + b16HALF); + } + else + { + /* quad[2] is at the bottom right of the triangle. Interpolate + * to get the corresponding point on the left side. + * + * Interpolation is from quad[0] along the line quad[0]->quad[1] + * which orthogonal to the slope of the line (and negative) + */ + + b16dxdy = -itob16(iheight) / iwidth; + + traps[0].bot.x1 = nxgl_interpolate(quad[0].x, quad[2].y - quad[0].y, b16dxdy); + traps[0].bot.x2 = quad[2].x; + traps[0].bot.y = b16toi(quad[2].y + b16HALF); + + /* quad[2] is at the top right of the second trapezoid. quad[1} is + * at the bottom left of the second trapezoid. Interpolate to get + * corresponding point on the right side. + * + * Interpolation is from quad[2] along the line quad[2]->quad[3] + * which as the same slope as the previous interpolation. + */ + + traps[1].top.x1 = traps[0].bot.x1; + traps[1].top.x2 = traps[0].bot.x2; + traps[1].top.y = traps[0].bot.y; + + traps[1].bot.x1 = quad[1].x; + traps[1].bot.x2 = nxgl_interpolate(traps[1].top.x2, quad[1].y - quad[2].y, b16dxdy); + traps[1].bot.y = b16toi(quad[1].y + b16HALF); + } + + /* The final trapezond (triangle) at the bottom is new well defined */ + + traps[2].top.x1 = traps[1].bot.x1; + traps[2].top.x2 = traps[1].bot.x2; + traps[2].top.y = traps[1].bot.y; + + traps[2].bot.x1 = quad[3].x; + traps[2].bot.x2 = quad[3].x; + traps[2].bot.y = b16toi(quad[3].y + b16HALF); } else { - /* Line is going "south west" */ - - b16x = itob16(line.pt1.x) + halfoffset; - iy = line.pt1.y + halfheight; - - traps[0].top.x1 = b16x - xoffset; - traps[0].top.x2 = traps[0].top.x1; - traps[0].top.y = iy - triheight + 1; - traps[0].bot.x1 = b16x - adjwidth + b16ONE; - traps[0].bot.x2 = b16x; - traps[0].bot.y = iy; - - b16x = itob16(line.pt2.x) - halfoffset; - iy = line.pt2.y - halfheight; - - traps[2].top.x1 = b16x; - traps[2].top.x2 = b16x + adjwidth - b16ONE; - traps[2].top.y = iy; - traps[2].bot.x1 = b16x + xoffset; - traps[2].bot.x2 = traps[2].bot.x1; - traps[2].bot.y = iy + triheight - 1; + /* Get the X positions of each point */ + + b16x = itob16(line.pt1.x); + quad[0].x = b16x - b16xoffset; + quad[1].x = b16x + b16xoffset; + + b16x = itob16(line.pt2.x); + quad[2].x = b16x - b16xoffset; + quad[3].x = b16x + b16xoffset; + + gvdbg("Southwest: quad (%08x,%08x),(%08x,%08x),(%08x,%08x),(%08x,%08x)\n", + quad[0].x, quad[0].y, quad[1].x, quad[1].y, + quad[2].x, quad[2].y, quad[3].x, quad[3].y); + + /* Now we can form the trapezoids. The top of the first trapezoid + * (triangle) is at quad[0] + */ + + traps[0].top.x1 = quad[0].x; + traps[0].top.x2 = quad[0].x; + traps[0].top.y = b16toi(quad[0].y + b16HALF); + + /* The bottom of the first trapezoid (triangle) may be either at + * quad[1] or quad[2], depending upon orientation. + */ + + if (quad[1].y < quad[2].y) + { + /* quad[1] is at the bottom right of the triangle. Interpolate + * to get the corresponding point on the left side. + * + * Interpolation is from quad[0] along the line quad[0]->quad[2] + * which as the same slope as the line (negative) + */ + + b16dxdy = -itob16(iwidth) / iheight; + + traps[0].bot.x1 = nxgl_interpolate(traps[0].top.x1, quad[1].y - quad[0].y, b16dxdy); + traps[0].bot.x2 = quad[1].x; + traps[0].bot.y = b16toi(quad[1].y + b16HALF); + + /* quad[1] is at the top right of the second trapezoid. quad[2} is + * at the bottom left of the second trapezoid. Interpolate to get + * corresponding point on the right side. + * + * Interpolation is from quad[1] along the line quad[1]->quad[3] + * which as the same slope as the line (negative) + */ + + traps[1].top.x1 = traps[0].bot.x1; + traps[1].top.x2 = traps[0].bot.x2; + traps[1].top.y = traps[0].bot.y; + + traps[1].bot.x1 = quad[2].x; + traps[1].bot.x2 = nxgl_interpolate(traps[1].top.x2, quad[2].y - quad[1].y, b16dxdy); + traps[1].bot.y = b16toi(quad[2].y + b16HALF); + } + else + { + /* quad[2] is at the bottom left of the triangle. Interpolate + * to get the corresponding point on the right side. + * + * Interpolation is from quad[0] along the line quad[0]->quad[1] + * which orthogonal to the slope of the line (and positive) + */ + + b16dxdy = itob16(iheight) / iwidth; + + traps[0].bot.x1 = quad[2].x; + traps[0].bot.x2 = nxgl_interpolate(traps[0].top.x2, quad[2].y - quad[0].y, b16dxdy); + traps[0].bot.y = b16toi(quad[2].y + b16HALF); + + /* quad[2] is at the top left of the second trapezoid. quad[1} is + * at the bottom right of the second trapezoid. Interpolate to get + * corresponding point on the left side. + * + * Interpolation is from quad[2] along the line quad[2]->quad[3] + * which as the same slope as the previous interpolation. + */ + + traps[1].top.x1 = traps[0].bot.x1; + traps[1].top.x2 = traps[0].bot.x2; + traps[1].top.y = traps[0].bot.y; + + traps[1].bot.x1 = nxgl_interpolate(traps[1].top.x1, quad[1].y - quad[2].y, b16dxdy); + traps[1].bot.x2 = quad[1].x; + traps[1].bot.y = b16toi(quad[1].y + b16HALF); + } + + /* The final trapezond (triangle) at the bottom is new well defined */ + + traps[2].top.x1 = traps[1].bot.x1; + traps[2].top.x2 = traps[1].bot.x2; + traps[2].top.y = traps[1].bot.y; + + traps[2].bot.x1 = quad[3].x; + traps[2].bot.x2 = quad[3].x; + traps[2].bot.y = b16toi(quad[3].y + b16HALF); } - /* The center parallelogram is the horizontal edge of each triangle. - * Note the minor inefficency: that horizontal edges are drawn twice. - */ + gvdbg("traps[0]: (%08x,%08x,%d),(%08x,%08x,%d)\n", + traps[0].top.x1, traps[0].top.x2, traps[0].top.y, + traps[0].bot.x1, traps[0].bot.x2, traps[0].bot.y); + gvdbg("traps[1]: (%08x,%08x,%d),(%08x,%08x,%d)\n", + traps[1].top.x1, traps[1].top.x2, traps[1].top.y, + traps[1].bot.x1, traps[1].bot.x2, traps[1].bot.y); + gvdbg("traps[2]: (%08x,%08x,%d),(%08x,%08x,%d)\n", + traps[2].top.x1, traps[2].top.x2, traps[2].top.y, + traps[2].bot.x1, traps[2].bot.x2, traps[2].bot.y); - traps[1].top.x1 = traps[0].bot.x1; - traps[1].top.x2 = traps[0].bot.x2; - traps[1].top.y = traps[0].bot.y; - - traps[1].bot.x1 = traps[2].top.x1; - traps[1].bot.x2 = traps[2].top.x2; - traps[1].bot.y = traps[2].top.y; - return 0; } @@ -330,12 +515,18 @@ int nxgl_splitline(FAR struct nxgl_vector_s *vector, * bottom. Just return the center parallelogram. */ - traps[1].top.x1 = itob16(line.pt1.x) - halfoffset; - traps[1].top.x2 = traps[1].top.x1 + adjwidth - 1; + traps[1].top.x1 = itob16(line.pt1.x - (linewidth >> 1)); + traps[1].top.x2 = traps[1].top.x1 + itob16(linewidth - 1); traps[1].top.y = line.pt1.y; - - traps[1].bot.x1 = itob16(line.pt2.x) - halfoffset; - traps[1].bot.x2 = traps[1].bot.x1 + adjwidth - 1; + + traps[1].bot.x1 = itob16(line.pt2.x - (linewidth >> 1)); + traps[1].bot.x2 = traps[1].bot.x1 + itob16(linewidth - 1); traps[1].bot.y = line.pt2.y; + + gvdbg("Horizontal traps[1]: (%08x,%08x,%d),(%08x,%08x, %d)\n", + traps[1].top.x1, traps[1].top.x2, traps[1].top.y, + traps[1].bot.x1, traps[1].bot.x2, traps[1].bot.y); + return 1; } + diff --git a/nuttx/include/nuttx/vt100.h b/nuttx/include/nuttx/vt100.h index d834f48f0c..32344a1deb 100644 --- a/nuttx/include/nuttx/vt100.h +++ b/nuttx/include/nuttx/vt100.h @@ -179,8 +179,8 @@ #define VT52_CLEAREOL {ASCII_ESC, 'K'} /* Erase to end of current line */ #define VT52_CLEAREOS {ASCII_ESC, 'J'} /* Erase to end of screen */ -#define VT52_IDENT {ASCII_ESC, 'Z'} /* dentify what the terminal is */ -#define VT52_IDENTRESP {ASCII_ESC, '/', 'Z'} /* Correct response to ident */ +#define VT52_IDENT {ASCII_ESC, 'Z'} /* Identify what the terminal is */ +#define VT52_IDENTRESP {ASCII_ESC, '/', 'Z'} /* Correct response to ident */ /* VT100 Special Key Codes * diff --git a/nuttx/libc/stdlib/lib_rand.c b/nuttx/libc/stdlib/lib_rand.c index bbefaee5d0..0faef5d66a 100644 --- a/nuttx/libc/stdlib/lib_rand.c +++ b/nuttx/libc/stdlib/lib_rand.c @@ -174,17 +174,22 @@ static inline void fgenerate2(void) { unsigned long randint; - /* Second order congruential generator. One may be added to the result of the - * generated value to avoid the value zero (I am not sure if this is necessary - * for higher order random number generators or how this may effect the quality - * of the generated numbers). - */ + /* Second order congruential generator. */ randint = (RND2_CONSTK1 * g_randint1 + RND2_CONSTK2 * g_randint2) % RND2_CONSTP; g_randint2 = g_randint1; - g_randint1 = (randint == 0 ? 1 : randint); + g_randint1 = randint; + + /* We cannot permit both values to become zero. That would be fatal for the + * second order random number generator. + */ + + if (g_randint2 == 0 && g_randint1 == 0) + { + g_randint2 = 1; + } } #if (CONFIG_LIB_RAND_ORDER == 2) @@ -207,11 +212,7 @@ static inline void fgenerate3(void) { unsigned long randint; - /* Third order congruential generator. One may be added to the result of the - * generated value to avoid the value zero (I am not sure if this is necessary - * for higher order random number generators or how this may effect the quality - * of the generated numbers). - */ + /* Third order congruential generator. */ randint = (RND3_CONSTK1 * g_randint1 + RND3_CONSTK2 * g_randint2 + @@ -219,7 +220,16 @@ static inline void fgenerate3(void) g_randint3 = g_randint2; g_randint2 = g_randint1; - g_randint1 = (randint == 0 ? 1 : randint); + g_randint1 = randint; + + /* We cannot permit all three values to become zero. That would be fatal for the + * third order random number generator. + */ + + if (g_randint3 == 0 && g_randint2 == 0 && g_randint1 == 0) + { + g_randint3 = 1; + } } static double_t frand3(void) diff --git a/nuttx/tools/Makefile.host b/nuttx/tools/Makefile.host index a661424dc8..4a46901e6a 100644 --- a/nuttx/tools/Makefile.host +++ b/nuttx/tools/Makefile.host @@ -44,11 +44,14 @@ ifneq ($(CONFIG_WINDOWS_NATIVE),y) HOSTCFLAGS += -D HAVE_STRTOK_C endif -all: mkconfig$(HOSTEXEEXT) mkversion$(HOSTEXEEXT) mksyscall$(HOSTEXEEXT) bdf-converter$(HOSTEXEEXT) mksymtab$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT) +all: b16$(HOSTEXEEXT) bdf-converter$(HOSTEXEEXT) cmpconfig$(HOSTEXEEXT) \ + mkconfig$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT) mksymtab$(HOSTEXEEXT) \ + mksyscall$(HOSTEXEEXT) mkversion$(HOSTEXEEXT) default: mkconfig$(HOSTEXEEXT) mksyscall$(HOSTEXEEXT) mkdeps$(HOSTEXEEXT) ifdef HOSTEXEEXT -.PHONY: clean mkconfig mkversion mksyscall bdf-converter mksymtab mkdeps +.PHONY: b16 bdf-converter cmpconfig clean mkconfig mkdeps mksymtab \ + mksyscall mkversion else .PHONY: clean endif @@ -58,6 +61,15 @@ endif HOSTCFLAGS ?= -O2 -Wall -I. HOSTCC ?= gcc +# b16 - Fixed precision math converstion tool + +b16$(HOSTEXEEXT): b16.c + $(Q) $(HOSTCC) $(HOSTCFLAGS) -o b16$(HOSTEXEEXT) b16.c + +ifdef HOSTEXEEXT +b16: b16$(HOSTEXEEXT) +endif + # mkconfig - Convert a .config file into a C config.h file mkconfig$(HOSTEXEEXT): mkconfig.c cfgparser.c @@ -69,8 +81,8 @@ endif # cmpconfig - Compare the contents of two configuration files -cmpconfig: cmpconfig.c - $(Q) $(HOSTCC) $(HOSTCFLAGS) -o cmpconfig cmpconfig.c +cmpconfig$(HOSTEXEEXT): cmpconfig.c + $(Q) $(HOSTCC) $(HOSTCFLAGS) -o cmpconfig$(HOSTEXEEXT) cmpconfig.c ifdef HOSTEXEEXT cmpconfig: cmpconfig$(HOSTEXEEXT) diff --git a/nuttx/tools/b16.c b/nuttx/tools/b16.c new file mode 100644 index 0000000000..66d581ffa6 --- /dev/null +++ b/nuttx/tools/b16.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * tools/b16.c + * + * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void show_usage(const char *progname) +{ + fprintf(stderr, "\nUSAGE: %s |\n", progname); + fprintf(stderr, "\nWhere:\n"); + fprintf(stderr, " :\n"); + fprintf(stderr, " A b16 fixed precision value in hexadecimal form: E.g., 0x00010000\n"); + fprintf(stderr, " Any value begininning with '0' will assumed by be hexadecimal format\n"); + fprintf(stderr, " :\n"); + fprintf(stderr, " A floating value in standard form: E.g., 5.1\n"); + exit(EXIT_FAILURE); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, char **argv, char **envp) +{ + double fvalue; + unsigned long ulvalue; + long lvalue; + const char *str; + char *endptr; + + /* There must be exactly one argument */ + + if (argc != 2) + { + fprintf(stderr, "\nExpected a single argument\n"); + show_usage(argv[0]); + } + str = argv[1]; + + /* If the value begins with a zero, we will assume that it is a hexadecimal + * representation. + */ + + if (str[0] == '0') + { + endptr = NULL; + ulvalue = strtoul(str, &endptr, 16); + if (!endptr || *endptr != '\0') + { + fprintf(stderr, "\nHexadecimal argument not fully converted\n"); + show_usage(argv[0]); + } + + if (ulvalue >= 0x80000000) + { + lvalue = ~ulvalue + 1; + } + else + { + lvalue = ulvalue; + } + + fvalue = ((double)lvalue) / 65536.0; + printf("0x%08lx -> %10.5f\n", ulvalue, fvalue); + } + else + { + endptr = NULL; + fvalue = strtod(str, &endptr); + if (!endptr || *endptr != '\0') + { + fprintf(stderr, "\nFloating point argument not fully converted\n"); + show_usage(argv[0]); + } + + lvalue = 65536.0 * fvalue; + printf("%10.5f -> 0x%08lx\n", fvalue, lvalue); + } + + return 0; +} diff --git a/nuttx/tools/cfgparser.c b/nuttx/tools/cfgparser.c index b1f189f6fb..1a35f78579 100644 --- a/nuttx/tools/cfgparser.c +++ b/nuttx/tools/cfgparser.c @@ -2,7 +2,7 @@ * tools/cfgpaser.c * * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <> + * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions