xfree86: Add option parsing for percent options.

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@who-t.net>
Reviewed-by: Dan Nicholson <dbn.lists@gmail.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Peter Hutterer 2010-05-18 11:12:49 +10:00 committed by Keith Packard
parent 673eb707ce
commit d88ba7721d
7 changed files with 102 additions and 1 deletions

View File

@ -339,6 +339,8 @@ optionTypeToSting(OptionValueType type)
return "[<bool>]"; return "[<bool>]";
case OPTV_FREQ: case OPTV_FREQ:
return "<freq>"; return "<freq>";
case OPTV_PERCENT:
return "<percent>";
default: default:
return ""; return "";
} }
@ -384,7 +386,8 @@ configureDeviceSection (int screennum)
" ### Available Driver options are:-\n" " ### Available Driver options are:-\n"
" ### Values: <i>: integer, <f>: float, " " ### Values: <i>: integer, <f>: float, "
"<bool>: \"True\"/\"False\",\n" "<bool>: \"True\"/\"False\",\n"
" ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\"\n" " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n"
" ### <percent>: \"<f>%\"\n"
" ### [arg]: arg optional\n"; " ### [arg]: arg optional\n";
ptr->dev_comment = xstrdup(descrip); ptr->dev_comment = xstrdup(descrip);
if (ptr->dev_comment) { if (ptr->dev_comment) {

View File

@ -51,6 +51,7 @@ typedef enum {
OPTV_ANYSTR, /* Any string, including an empty one */ OPTV_ANYSTR, /* Any string, including an empty one */
OPTV_REAL, OPTV_REAL,
OPTV_BOOLEAN, OPTV_BOOLEAN,
OPTV_PERCENT,
OPTV_FREQ OPTV_FREQ
} OptionValueType; } 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 double xf86SetRealOption(pointer optlist, const char *name, double deflt);
extern _X_EXPORT char *xf86SetStrOption(pointer optlist, const char *name, char *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 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 int xf86CheckIntOption(pointer optlist, const char *name, int deflt);
extern _X_EXPORT double xf86CheckRealOption(pointer optlist, const char *name, double 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 char *xf86CheckStrOption(pointer optlist, const char *name, char *deflt);
extern _X_EXPORT int xf86CheckBoolOption(pointer list, const char *name, int 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 xf86AddNewOption(pointer head, const char *name, const char *val );
extern _X_EXPORT pointer xf86NewOption(char *name, char *value ); extern _X_EXPORT pointer xf86NewOption(char *name, char *value );
extern _X_EXPORT pointer xf86NextOption(pointer list ); 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 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 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 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); extern _X_EXPORT pointer xf86ReplaceStrOption(pointer optlist, const char *name, const char* val);
#endif #endif

View File

@ -223,6 +223,18 @@ LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed)
return deflt; 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 */ /* These xf86Set* functions are intended for use by non-screen specific code */
int int
@ -252,6 +264,12 @@ xf86SetBoolOption(pointer optlist, const char *name, int deflt)
return LookupBoolOption(optlist, name, deflt, TRUE); 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 * These are like the Set*Option functions, but they don't mark the options
* as used. * as used.
@ -283,6 +301,12 @@ xf86CheckBoolOption(pointer optlist, const char *name, int deflt)
return LookupBoolOption(optlist, name, deflt, FALSE); 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 * addNewOption() has the required property of replacing the option value
* if the option is already present. * if the option is already present.
@ -309,6 +333,14 @@ xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val)
return xf86AddNewOption(optlist,name,val?"True":"False"); return xf86AddNewOption(optlist,name,val?"True":"False");
} }
pointer
xf86ReplacePercentOption(pointer optlist, const char *name, const double val)
{
char tmp[16];
sprintf(tmp, "%lf%%", val);
return xf86AddNewOption(optlist,name,tmp);
}
pointer pointer
xf86ReplaceStrOption(pointer optlist, const char *name, const char* val) xf86ReplaceStrOption(pointer optlist, const char *name, const char* val)
{ {
@ -533,6 +565,21 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
p->found = FALSE; p->found = FALSE;
} }
break; 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: case OPTV_FREQ:
if (*s == '\0') { if (*s == '\0') {
xf86DrvMsg(scrnIndex, X_WARNING, xf86DrvMsg(scrnIndex, X_WARNING,

View File

@ -70,6 +70,8 @@ optionTypeToSting(OptionValueType type)
return "<bool>"; return "<bool>";
case OPTV_FREQ: case OPTV_FREQ:
return "<freq>"; return "<freq>";
case OPTV_PERCENT:
return "<percent>";
default: default:
return "<undef>"; return "<undef>";
} }

View File

@ -2528,6 +2528,7 @@ Next, the higher level functions that most drivers would use.
OPTV_ANYSTR, /* Any string, including an empty one */ OPTV_ANYSTR, /* Any string, including an empty one */
OPTV_REAL, OPTV_REAL,
OPTV_BOOLEAN, OPTV_BOOLEAN,
OPTV_PERCENT,
OPTV_FREQ OPTV_FREQ
} OptionValueType; } OptionValueType;
@ -2555,6 +2556,11 @@ Next, the higher level functions that most drivers would use.
&s.code;freq.units&e.code; is set to &s.code;0&e.code;, and &s.code;freq.units&e.code; is set to &s.code;0&e.code;, and
&s.code;freq.freq&e.code; is unscaled. &s.code;freq.freq&e.code; is unscaled.
&s.code;OPTV_PERCENT&e.code; can be used for option values that are
specified in percent (e.g. "20%"). These values are a floating point
number with a percent sign appended. If the percent sign is missing,
the parser will fail to match the value.
Typical usage is to setup an array of Typical usage is to setup an array of
&s.code;OptionInfoRecs&e.code; with all fields initialised. &s.code;OptionInfoRecs&e.code; with all fields initialised.
The &s.code;value&e.code; and &s.code;found&e.code; fields get The &s.code;value&e.code; and &s.code;found&e.code; fields get

View File

@ -673,6 +673,18 @@ winSetRealOption (pointer optlist, const char *name, double deflt)
deflt = o.value.realnum; deflt = o.value.realnum;
return deflt; return deflt;
} }
double
winSetPercentOption (pointer optlist, const char *name, double deflt)
{
OptionInfoRec o;
o.name = name;
o.type = OPTV_PERCENT;
if (ParseOptionValue (-1, optlist, &o))
deflt = o.value.realnum;
return deflt;
}
#endif #endif
@ -851,6 +863,31 @@ ParseOptionValue (int scrnIndex, pointer options, OptionInfoPtr p)
p->found = FALSE; p->found = FALSE;
} }
break; break;
case OPTV_PERCENT:
if (*s == '\0')
{
winDrvMsg (scrnIndex, X_WARNING,
"Option \"%s\" requires a percent value\n",
p->name);
p->found = FALSE;
}
else
{
double percent = strtod (s, &end);
if (end != s && winNameCompare (end, "%"))
{
p->found = TRUE;
p->value.realnum = percent;
}
else
{
winDrvMsg (scrnIndex, X_WARNING,
"Option \"%s\" requires a frequency value\n",
p->name);
p->found = FALSE;
}
}
case OPTV_FREQ: case OPTV_FREQ:
if (*s == '\0') if (*s == '\0')
{ {

View File

@ -256,6 +256,7 @@ typedef enum
OPTV_ANYSTR, /* Any string, including an empty one */ OPTV_ANYSTR, /* Any string, including an empty one */
OPTV_REAL, OPTV_REAL,
OPTV_BOOLEAN, OPTV_BOOLEAN,
OPTV_PERCENT,
OPTV_FREQ OPTV_FREQ
} }
OptionValueType; OptionValueType;
@ -289,6 +290,7 @@ char *winSetStrOption (pointer optlist, const char *name, char *deflt);
int winSetBoolOption (pointer optlist, const char *name, int deflt); int winSetBoolOption (pointer optlist, const char *name, int deflt);
int winSetIntOption (pointer optlist, const char *name, int deflt); int winSetIntOption (pointer optlist, const char *name, int deflt);
double winSetRealOption (pointer optlist, const char *name, double deflt); double winSetRealOption (pointer optlist, const char *name, double deflt);
double winSetPercentOption (pointer optlist, const char *name, double deflt);
#ifdef XWIN_XF86CONFIG #ifdef XWIN_XF86CONFIG
XF86OptionPtr winFindOption (XF86OptionPtr list, const char *name); XF86OptionPtr winFindOption (XF86OptionPtr list, const char *name);
char *winFindOptionValue (XF86OptionPtr list, const char *name); char *winFindOptionValue (XF86OptionPtr list, const char *name);