Skip to content

Commit

Permalink
Add math expansion variables.
Browse files Browse the repository at this point in the history
  This adds new expansion variables $[math.add.<x>.<y>],
  $[math.subtract.<x>.<y>], $[math.multiply.<x>.<y>],
  $[math.divide.<x>.<y>], and $[math.mod.<x>.<y>], which can be
  used to do basic integer mathematics on the integers <x> and <y>.
  This also updates the default-config to use these expansion
  variables instead of a shell to do the mathematics in its size
  computation.
  • Loading branch information
somiaj committed Apr 2, 2024
1 parent 1758aaa commit 609a777
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 6 deletions.
8 changes: 4 additions & 4 deletions default-config/config
Original file line number Diff line number Diff line change
Expand Up @@ -637,10 +637,10 @@ DestroyModuleConfig RightPanel:*
Test (x stalonetray) *RightPanel: (120x20, Swallow(NoClose,UseOld) \
stalonetray 'Exec exec stalonetray --config \
"$[FVWM_DATADIR]/default-config/stalonetrayrc"', Frame 0)
Test (x stalonetray) PipeRead 'echo "*RightPanel: (120x$(($[monitor.$[monitor.primary].height]-225)), \
Top, Swallow FvwmIconMan \'Module FvwmIconMan\', Frame 0)"'
Test (!x stalonetray) PipeRead 'echo "*RightPanel: (120x$(($[monitor.$[monitor.primary].height]-205)),\
Top, Swallow FvwmIconMan \'Module FvwmIconMan\', Frame 0)"'
Test (x stalonetray) *RightPanel: (120x$[math.-.$[monitor.$[monitor.primary].height].225], \
Top, Swallow FvwmIconMan \'Module FvwmIconMan\', Frame 0)
Test (!x stalonetray) *RightPanel: (120x$[math.-.$[monitor.$[monitor.primary].height].205], \
Top, Swallow FvwmIconMan \'Module FvwmIconMan\', Frame 0)
*RightPanel: (120x45, Swallow DateTime 'Module FvwmScript FvwmScript-DateTime',\
Frame 0)
*RightPanel: (120x5, Frame 0)
Expand Down
20 changes: 19 additions & 1 deletion doc/fvwm3_manpage_source.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1616,7 +1616,6 @@ $[screen.count]::
+
This is deprecated; use $[monitor.count] instead.


$[fg.cs<n>] $[bg.cs<n>] $[hilight.cs<n>] $[shadow.cs<n>] $[fgsh.cs<n>]::
These parameters are replaced with the name of the foreground (fg),
background (bg), hilight (hilight), shadow (shadow), or the font shadow
Expand All @@ -1636,6 +1635,25 @@ $[bg.cs3.lighten15.hash].
+
Please refer to the *Colorsets* section for details about colorsets.

$[math.+.<x>.<y>] $[math.-.<x>.<y>] $[math.*.<x>.<y>] $[math./.<x>.<y>] $[math.%.<x>.<y>] $[math.^.<x>.<y>]::
The math expansion variables can be used to do some basic arithmetic
on the integers <x> and <y>. These expressions can be used to add
({plus}), subtract (-), multiply ({asterisk}), divide (/), modulus
(%), and exponentiation ({caret}). This can be useful when computing
the size of panels or locations of windows relative to a monitor, for
example $[math.-.$[monitor.$[monitor.primary].height].200] will
subtract 200 pixels from the height of the primary monitor. These can
also be nested for more complex operations,
$[math.{plus}.$[math.{asterisk}.3.5].$[math.-.4.-2]]
is replaced with 21.
+
All operations use C integer mathematics. The result of integer
division is the quotient. The modulus can be used to get the remainder
of the integer division. Note that the C modulus returns negative
remainders for negative values. Finally the exponentiation operation
only makes sense for positive values of <y>. If <y> is zero or
negative, exponentiation will return 1.

$[schedule.last]::
This is replaced by the id of the last command that was scheduled with
the *Schedule* command, even if this command was already executed.
Expand Down
54 changes: 53 additions & 1 deletion fvwm/expand.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ static char *partial_function_vars[] =
"infostore.",
"monitor.",
"shadow.cs",
"math.",
NULL
};

Expand Down Expand Up @@ -164,7 +165,8 @@ enum
VAR_HILIGHT_CS,
VAR_INFOSTORE_,
VAR_MONITOR_,
VAR_SHADOW_CS
VAR_SHADOW_CS,
VAR_MATH_,
} partial_extended_vars;

enum
Expand Down Expand Up @@ -672,6 +674,56 @@ static signed int expand_vars_extended(
}
break;
}
case VAR_MATH_:
if (rest == NULL || rest[1] != '.')
{
/* parsing error */
return -1;
}
l = rest[0];
rest += 2;
if (sscanf(rest, "%d.%d%n", &x, &y, &n) < 2)
{
/* parsing error */
return -1;
}
if (*(rest + n) != 0)
{
/* trailing characters */
return -1;
}
switch (l) {
case '+':
val = x + y;
break;
case '-':
val = x - y;
break;
case '*':
val = x * y;
break;
case '/':
val = x / y;
break;
case '%':
val = x % y;
break;
case '^':
val = 1;
/* Should we limit the value of y here? */
for (i = 0; i < y; i++)
{
val *= x;
}
break;
default:
/* undefined operation */
return -1;
}

is_numeric = True;
goto GOT_STRING;
break;
default:
break;
}
Expand Down

0 comments on commit 609a777

Please sign in to comment.