Wednesday, February 9, 2011

Env var puzzle in csh

Today (means: some day in May 2008) I spent some time trouble shooting a strange issue until I finally got to the solution so I wrote this blog entry as an educational excercise to show the trouble shooting efforts I went through.

This was on a Solaris 10 machine.

The puzzle

I was working in a terminal window (xterm to be precise) where I had been doing some work throughout the day and I finally got to the point to set an environment variable and check its value (my login shell is csh).

foo:/home/andreas 151 % setenv THIS something
foo:/home/andreas 152 % echo T=$THIS
T=
Oh, I just set the variable and then it reports to be empty? How strange.
I checked the environment:
foo:/home/andreas 153 % env | grep THIS
THIS=something
So this looks ok, the var is definitly set but why does echo report it as empty? (and printf showed the same).

I tested other variable names but they behaved normal: echo showed their values.

I opened a new terminal window and tested this particular variable and others: all worked normal.

How can that be? What was so special about this session?

I trussed echo (for the non-Solaris users: truss is the Solaris command to inspect the behaviour of processes showing system calls etc.) and I saw that it is called without an argument, its env list shows THIS to be set though:
foo:/home/andreas 157 % truss -aeilf -r all -v all echo $THIS
26445/1:        execve("/usr/bin/echo", 0xFFBFE954, 0xFFBFE95C)  argc = 1
26445/1:         argv: echo
26445/1:         envp: USER=andreash LOGNAME=andreash HOME=/home/andreash
26445/1:          ...
26445/1:          THIS=something
...
Think about this for a while before you proceed to the next section for the solution.

The solution

I finally got to the point where I started to check other things which are set in csh: aliases and variables (not env).

The list of aliases did not show anything particular.

And then I ran set:
foo:/home/andreas 161 % set
CSHRC   /home/andreas/.cshrc
HOSTNAME    foo
...
THIS
...
So here you go: in some of my previous work that day in that particular terminal I must have set the variable THIS to empty and forgotten about it and despite setting the environment variable the first setting was still taken into account.
This is one of the traps of csh (others might call it feature, and of course this was new to me).
The Bourne shell family uses export to distinguish and this trap does not exist.

Summary

Here it is again in summary to remember:
in csh when you 'set' a variable a subsequent 'setenv' will not replace the variable in the current context.
set A=aaaaaa
setenv A bbbbbb
echo A=$A
A=aaaaaa

unset A
echo A=$A
A=bbbbbb
Going a little further: if you reverse this and first set a variable via setenv and then via set the second value will prevail
setenv A bbbbbb
set A aaaaaa
echo A=$A
A=aaaaaa
i.e. variables set with set always take precedence over variables set with setenv. Very important to remember. And only the latter will be exported to new shells though. I guess it would be a wise rule to keep a distinct set of names for set/setenv, otherwise things can get confusing (as in my starting puzzle) or things can even go wrong (when programming with false assumptions).

Tuesday, February 8, 2011

Conditional formatting in OpenOffice.org

What is conditional formatting? It means applying certain attributes to a spreadsheet cell (e.g. background, font size, ...) depending on some conditions being met or not. The conditions are based on the content of the cell or - in more complex cases - on other cells.

In OpenOffice.org there are two steps necessary:
  • Create appropriate styles (to be chosen from)
  • Set the conditional formatting for selected cells

This is different to Excel where one selects cells, sets the condition and chooses a format. In my view OpenOffice.org is more flexible because of its simplicity of change: if you want to change the format simply edit the style and the change is applied to wherever the style is being used, be it part of the conditional formatting or elsewhere. (I'm not an Excel expert though.)

Create the appropriate styles

  • Click F11 or Format->Styles and Formatting
  • Choose cell styles
  • Move the mouse to the blank middle of the styles window and right click and press 'New...'
  • Choose a style name e.g. RedBg, then choose the Background tab and set your colour, press OK or change any other attribute e.g. font type and size in the Font tab.
Do this for as many styles as you need, so that you have e.g. 3 new named styles for various backgrounds likeRedBg, GreenBg, AmberBg

Set the conditional formatting

  • Select the cell or cell range
  • Choose Format -> Conditional Formatting...
  • Set the conditions
    • Example based on numeric values of the cells
        condition 1: 'cell value is' less than 10 and select style RedBg
        condition 2: 'cell value is' less than 20 and select style AmberBg
        condition 3: 'cell value is' greater than or equal to 20 and select style GreenBg
      This also shows how to use conditions in ascending order: if the first condition is met then its style is applied. If not then the second condition will be checked aso.
    • Example based on textual values of the cells
        condition 1 'formula is' exact(lower(c5);"no") and select style RedBg
        condition 2 'formula is' exact(lower(c5);"yes") and select style GreenBg
      The background will be set to either red or green depending on no/yes entries in whichever case.
      Important to note: the cell reference c5 should be the lower right hand corner of your cell range
More complex cases are to use conditional formatting based on the entries of other cells or multiple cells, you'd need to construct the conditions as formulas using the appropriate functions.

If you need more than 3 conditions I'm afraid only a macro will get you going.