[PATCH v2] xfree86: Add option parsing for percent options.

Peter Hutterer peter.hutterer at who-t.net
Sun May 16 19:52:47 PDT 2010


In some cases, an option of "50%" would be preferable over fixed value
configuration - especially if the actual values are autoprobed.
Add a new set of functions to parse percent values from configurations.

The percent value parsing differs slightly - if the option is not to marked
as used (e.g. xf86CheckPercentOption()), no warning is emitted to the log
file if the value is not a percent value. This allows double-options (either
as % or as absolute number) without warnings.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---

Changes since v1:
- use double instead of int
- no special warning handling for % options, drivers should work around this.
- sscanf format changed to %c instead of %1[%].

 hw/xfree86/common/xf86Opt.h    |    4 +++
 hw/xfree86/common/xf86Option.c |   47 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/hw/xfree86/common/xf86Opt.h b/hw/xfree86/common/xf86Opt.h
index ce3d767..d75d3bf 100644
--- a/hw/xfree86/common/xf86Opt.h
+++ b/hw/xfree86/common/xf86Opt.h
@@ -51,6 +51,7 @@ typedef enum {
     OPTV_ANYSTR,                /* Any string, including an empty one */
     OPTV_REAL,
     OPTV_BOOLEAN,
+    OPTV_PERCENT,
     OPTV_FREQ
 } OptionValueType;
 
@@ -72,10 +73,12 @@ extern _X_EXPORT int xf86SetIntOption(pointer optlist, const char *name, int def
 extern _X_EXPORT double xf86SetRealOption(pointer optlist, const char *name, double deflt);
 extern _X_EXPORT char *xf86SetStrOption(pointer optlist, const char *name, char *deflt);
 extern _X_EXPORT int xf86SetBoolOption(pointer list, const char *name, int deflt );
+extern _X_EXPORT double xf86SetPercentOption(pointer list, const char *name, double deflt );
 extern _X_EXPORT int xf86CheckIntOption(pointer optlist, const char *name, int deflt);
 extern _X_EXPORT double xf86CheckRealOption(pointer optlist, const char *name, double deflt);
 extern _X_EXPORT char *xf86CheckStrOption(pointer optlist, const char *name, char *deflt);
 extern _X_EXPORT int xf86CheckBoolOption(pointer list, const char *name, int deflt );
+extern _X_EXPORT double xf86CheckPercentOption(pointer list, const char *name, double deflt );
 extern _X_EXPORT pointer xf86AddNewOption(pointer head, const char *name, const char *val );
 extern _X_EXPORT pointer xf86NewOption(char *name, char *value );
 extern _X_EXPORT pointer xf86NextOption(pointer list );
@@ -109,5 +112,6 @@ extern _X_EXPORT char *xf86NormalizeName(const char *s);
 extern _X_EXPORT pointer xf86ReplaceIntOption(pointer optlist,  const char *name, const int val);
 extern _X_EXPORT pointer xf86ReplaceRealOption(pointer optlist,  const char *name, const double val);
 extern _X_EXPORT pointer xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val);
+extern _X_EXPORT pointer xf86ReplacePercentOption(pointer optlist, const char *name, const double val);
 extern _X_EXPORT pointer xf86ReplaceStrOption(pointer optlist,  const char *name, const char* val);
 #endif
diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
index a2868bf..7971837 100644
--- a/hw/xfree86/common/xf86Option.c
+++ b/hw/xfree86/common/xf86Option.c
@@ -223,6 +223,18 @@ LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed)
     return deflt;
 }
 
+static int
+LookupPercentOption(pointer optlist, const char *name, double deflt, Bool markUsed)
+{
+    OptionInfoRec o;
+
+    o.name = name;
+    o.type = OPTV_PERCENT;
+    if (ParseOptionValue(-1, optlist, &o, markUsed))
+	deflt = o.value.realnum;
+    return deflt;
+}
+
 /* These xf86Set* functions are intended for use by non-screen specific code */
 
 int
@@ -252,6 +264,12 @@ xf86SetBoolOption(pointer optlist, const char *name, int deflt)
     return LookupBoolOption(optlist, name, deflt, TRUE);
 }
 
+double
+xf86SetPercentOption(pointer optlist, const char *name, double deflt)
+{
+    return LookupPercentOption(optlist, name, deflt, TRUE);
+}
+
 /*
  * These are like the Set*Option functions, but they don't mark the options
  * as used.
@@ -283,6 +301,12 @@ xf86CheckBoolOption(pointer optlist, const char *name, int deflt)
     return LookupBoolOption(optlist, name, deflt, FALSE);
 }
 
+
+double
+xf86CheckPercentOption(pointer optlist, const char *name, double deflt)
+{
+    return LookupPercentOption(optlist, name, deflt, FALSE);
+}
 /*
  * addNewOption() has the required property of replacing the option value
  * if the option is already present.
@@ -310,6 +334,14 @@ xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val)
 }
 
 pointer
+xf86ReplacePercentOption(pointer optlist, const char *name, const double val)
+{
+    char tmp[16];
+    sprintf(tmp, "%lf%%", val);
+    return xf86AddNewOption(optlist,name,tmp);
+}
+
+pointer
 xf86ReplaceStrOption(pointer optlist, const char *name, const char* val)
 {
       return xf86AddNewOption(optlist,name,val);
@@ -533,6 +565,21 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
 		p->found = FALSE;
 	    }
 	    break;
+	case OPTV_PERCENT:
+	    {
+		char tmp = 0;
+		/* awkward match, but %% doesn't increase the match counter,
+		 * hence 100 looks the same as 100% to the caller of sccanf
+		 */
+		if (sscanf(s, "%lf%c", &p->value.realnum, &tmp) != 2 || tmp != '%') {
+		    xf86DrvMsg(scrnIndex, X_WARNING,
+			       "Option \"%s\" requires a percent value\n", p->name);
+		    p->found = FALSE;
+		} else {
+		    p->found = TRUE;
+		}
+	    }
+	    break;
 	case OPTV_FREQ:	
 	    if (*s == '\0') {
 		xf86DrvMsg(scrnIndex, X_WARNING,
-- 
1.7.0.1



More information about the xorg-devel mailing list