patternbashMinor
cpupower bash completion script
Viewed 0 times
completioncpupowerbashscript
Problem
I wrote a bash completion script for the
It supports all the subcommands of
```
## Autocompletion bash for the command 'cpupower'
## This software is released into the public domain
## Known bugs, incomplete stuff:
## #000001. Doesn't complete, or validate at all, the cpu list accepted by -c|--cpu
## #000002. There are no man page for 'cpupower idle-info', so his parameters are not supported
## #000003. Doesn't complete or validate any of the command arguments' values
## * The governor option in frequency-set command is now supported
# Indicate if an item is present in an array
# Usage: in_array "$ITEM" "${ARRAY[@]}"
in_array()
{
local ITEM
for ITEM in "${@:2}"; do [[ "$ITEM" == "$1" ]] && return 0; done
return 1
}
_cpupower()
{
# Global flags
local FLAG_DEBUG=1
local FLAG_CPU=2
local FLAG_COMPGEN_COMMAND=4
local FLAGS=0
# frequency-info command flags
local FLAG_FREQINFOSET_OUTPUT=1
local FLAG_FREQINFOSET_HUMAN=2
local FLAG_FREQINFOSET_PROC=4
local FLAGS_FREQINFO=0
# frequency-set command flags
local FLAG_FREQSET_MIN=1
local FLAG_FREQSET_MAX=2
local FLAG_FREQSET_GOV=4
local FLAG_FREQSET_FREQ=8
local FLAG_FREQSET_RELATED=16
local FLAGS_FREQSET=0
# info & set command flags
local FLAG_INFOSET_PERFBIAS=1
local FLAG_INFOSET_SCHEDMC=2
local FLAG_INFOSET_SCHEDSMT=4
local FLAGS_INFOSET=0
# monitor command flags
local FLAG_MONITOR_LIST=1
local FLAG_MONITOR_INTERVAL=2
local FLAG_MONITOR_ONLY=4
local FLAG_MONITOR_SCHED=8
local FLAG_MONITOR_VERBOSE=16
local FLAGS_MONITOR=0
# States
local STATE_BASE=0 # Initial
local STATE_CPU_WAITING=1 # Waiting Cpu list
local STATE_COMMAND_WAITING=2 # Waiting comm
cpupower command but I feel that it sucks. It's too long for such a simple task and have too much case/if-else nesting.It supports all the subcommands of
cpupower and their options but not the values. It also support the incompatibilities between some options.```
## Autocompletion bash for the command 'cpupower'
## This software is released into the public domain
## Known bugs, incomplete stuff:
## #000001. Doesn't complete, or validate at all, the cpu list accepted by -c|--cpu
## #000002. There are no man page for 'cpupower idle-info', so his parameters are not supported
## #000003. Doesn't complete or validate any of the command arguments' values
## * The governor option in frequency-set command is now supported
# Indicate if an item is present in an array
# Usage: in_array "$ITEM" "${ARRAY[@]}"
in_array()
{
local ITEM
for ITEM in "${@:2}"; do [[ "$ITEM" == "$1" ]] && return 0; done
return 1
}
_cpupower()
{
# Global flags
local FLAG_DEBUG=1
local FLAG_CPU=2
local FLAG_COMPGEN_COMMAND=4
local FLAGS=0
# frequency-info command flags
local FLAG_FREQINFOSET_OUTPUT=1
local FLAG_FREQINFOSET_HUMAN=2
local FLAG_FREQINFOSET_PROC=4
local FLAGS_FREQINFO=0
# frequency-set command flags
local FLAG_FREQSET_MIN=1
local FLAG_FREQSET_MAX=2
local FLAG_FREQSET_GOV=4
local FLAG_FREQSET_FREQ=8
local FLAG_FREQSET_RELATED=16
local FLAGS_FREQSET=0
# info & set command flags
local FLAG_INFOSET_PERFBIAS=1
local FLAG_INFOSET_SCHEDMC=2
local FLAG_INFOSET_SCHEDSMT=4
local FLAGS_INFOSET=0
# monitor command flags
local FLAG_MONITOR_LIST=1
local FLAG_MONITOR_INTERVAL=2
local FLAG_MONITOR_ONLY=4
local FLAG_MONITOR_SCHED=8
local FLAG_MONITOR_VERBOSE=16
local FLAGS_MONITOR=0
# States
local STATE_BASE=0 # Initial
local STATE_CPU_WAITING=1 # Waiting Cpu list
local STATE_COMMAND_WAITING=2 # Waiting comm
Solution
-
Yes this starts to look a bit like godzilla, no dealbreaker though.
-
Divide this bulk in several parts. Here some tips to get started:
-
Start moving all your variable declarations to a separate file which you will source. This is going to be your config file.
We are talking about the first 80 lines of your
-
Move big items you have in your outer
So you get
-
Big static sequences of commands feel best at home in a function.
What they do can easily be described in a few words. So these words can be the name of the function. This way the blocks are easy to manouver inside the code.
-
If you grow a lot of (small and clear) functions, put them in a separate file which you can source, and sort them in categories alphabetically. This way you can find them quickly. Consider this file as a "library" so you have a sort of a guideline how to handle it. It also makes it very easy to add or remove extra functionality without hacking away in the one-big-file
If you do these things you will see that it will not only look much smaller and easier to handle but also that you can enable and disable entire parts on the fly with a single
tl:dr
Above tips creates a construction/framework that makes slimming down the code selectively a much easier task. It also makes you more efficient in optimizing a thing or two.
Well, these were the answers to your questions. If these answers brought you some more questions, don't hesitate to ask.
Yes this starts to look a bit like godzilla, no dealbreaker though.
-
Divide this bulk in several parts. Here some tips to get started:
-
Start moving all your variable declarations to a separate file which you will source. This is going to be your config file.
We are talking about the first 80 lines of your
_cpupower() function here. That is almost 30% of your total amount of lines (!)-
Move big items you have in your outer
case construct, to separate functions. Especially the nested case and the big if/elif parts.So you get
case and esac at least on the same page. This will make debugging a lot easier.-
Big static sequences of commands feel best at home in a function.
What they do can easily be described in a few words. So these words can be the name of the function. This way the blocks are easy to manouver inside the code.
-
If you grow a lot of (small and clear) functions, put them in a separate file which you can source, and sort them in categories alphabetically. This way you can find them quickly. Consider this file as a "library" so you have a sort of a guideline how to handle it. It also makes it very easy to add or remove extra functionality without hacking away in the one-big-file
If you do these things you will see that it will not only look much smaller and easier to handle but also that you can enable and disable entire parts on the fly with a single
#. Also is this the best starting position if you want to slim down the code effectively. By having a better overview you will spot optimization possibilities sooner and with more easetl:dr
- every
case-esacin its own function (possibly a separate file)
- every big
if/elifsequence in its own function (possibly a separate file)
- every simple sequence or stanza of commands in its own function
- all 80 declarations together in a config file
- all functions together in a library file
Above tips creates a construction/framework that makes slimming down the code selectively a much easier task. It also makes you more efficient in optimizing a thing or two.
Well, these were the answers to your questions. If these answers brought you some more questions, don't hesitate to ask.
Context
StackExchange Code Review Q#32499, answer score: 5
Revisions (0)
No revisions yet.