Thursday 28 June 2007

graphviz bug 1042 (right-click mouse menus not selectable) is probably 524 (numlock)

Yesterday I discovered that NumLock being on made mouse menus in graphviz tools not work.
Stupid silly thing but actually not intuitively solved.
Poking around (on nternet with google) further I think this could be a more general X programming problem.
My problem is with cygwin and solaris X clients (and cygwin X server[you know about that weird X server-client switcheroo don't you?]).

Further poking:

  Use 'xev' to trace X events
  Only difference is with NumLock on event state is 0x10 and 0x410, with off state is 0 and 0x400.

  On solaris truss dotty process (lefty) truss -u a.out and truss -u lib,libX* -t '!all'
  Interesting to note that with NumLock on then there are no events when scrolling or selecting
  mouse menu item.  So it is as if the application just has not registered for those events.
  So it is a problem at X setup/initialise time.

  checkout cvs source, update cygwin dependancies (autoconf, gd, libtool, more!),
   # augh! autoconf fails because it thinks gettext is not there :(

 download latest stable graphviz source
  ./configure; make; make install
  # That works now, hurmmm. Yikers, Okay there is windows, gtk and X gui interface.  (in  cmd/lefty/ws/)

 take a simple X  application.
 That works and isn't bothered by numlock.
 Has very different X initialisation though, leaves much more to default X stuff.
 Humm. If could find a very simple example which had the numlock bad behaviour it would make finding the
 solution easier.
 Humm :-7 http://www.xfree86.org/4.4.0/XtAppAddActions.3.html
 http://www.xfree86.org/current/XtAddCallback.3.html
 http://www.cs.cf.ac.uk/Dave/X_lecture/X_book_caller/ push me!

Oh, By the way. For graphviz on cygwin (and a couple of other things) add this to  your  cygwin download sites (in Setup): http://lassauge.free.fr/cygwin



graphviz bug 1042 description isn't great, "right-click mouse menus not selectable" would be better.
A right click raises menu but nothing may be selected.

I saw bug 524 (old and closed) to do with num-lock.
It looks to me that 524 is duplicate of 1042.

I also of course see this bug (solaris and cygwin).
I toggled num-lock and hey presto the menus work.
This behaviour is very puzzling and most new users would not find the very simple solution!

It should not matter about numlock.

dot version 2.2 (Wed Mar 23 14:44:07 UTC 2005)
 on cygwin

also:
dot version 1.10 (Wed Jan  5 16:56:31 GMT 2005)
 on solaris 10(sparc)
from sunfreeware.com package:
/usr/sbin/pkgchk -l -p `which dot`
        SFWgviz

both using cygwin as X server


http://www.graphviz.org/bugs/b1042.html

http://www.graphviz.org/bugs/b524.html

http://www.google.ie/search?as_q=mouse&hl=en&client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&hs=G2&num=10&btnG=Google+Search&as_epq=&as_oq=&as_eq=&lr=&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=http%3A%2F%2Fwww.graphviz.org%2Fbugs%2F&as_rights=&safe=images

subversion move/rename and branch merge problem

Fionn is reading writing books at the moment and I find myself trying to  express and craft a warning about svn. "We want to give instructions to people on how to avoid problems I think. (and not confuse them too much with details - keep the details for our reference) It's difficult to write something simple and yet cover the problem entirely! :)" - me


WARNING: Everyone should be cautious renaming or moving things in svn.

If someone is moving(or renaming)(or deleting) directories/files then all people working off of the same branch should be notified.  It would actually be best if all work was finished up and the move/rename done while there were as few other branches off of the same branch as possible. (as few as possible = zero! - :) ) If anyone has changes to files that are renamed or moved they should be aware that their changes will be lost by any merge.

Why?

Subversion rename/move is implemented as seperate Delete and Add and this means it is as if a new entity is added at the point the rename/move is comitted. Any changes to moved entities done in parallel (and comitted after move) will be merged out and lost.




A simplest example (not with branches/merge), but results in the same problem.
Essentially a directory move was committed.
Another user had edited the files in that directory.
When that user updated from trunk the file changes were "lost".

# mary edits file
"fudir/new-fu-file.c" 3 lines, 36 characters

mary$ svn status
M      fudir/new-fu-file.c


# Meanwhile Tom is reorganising stuff. (move dir and COMMIT)

tom$ svn mv fudir/ fu-moved/
A         fu-moved
D         fudir/new-fu-file.c
D         fudir

tom$ svn ci -m"mv fudir to fu-moved"
Deleting       fudir
Adding         fu-moved

Committed revision 12.


# Mary can see there are updates and she cannot commit until after update.

mary$ svn status
M      fudir/new-fu-file.c

mary$ svn status -u
       *            fu-moved/new-fu-file.c
       *            fu-moved
M              11   fudir/new-fu-file.c
       *       11   fudir
Status against revision:     12

mary$ svn ci -m"commit to file moved away by other checkout"
Sending        trunk
svn: Commit failed (details follow):
svn: Out of date: '/trunk' in transaction '12-1'

mary$ svn up
D    fudir
A    fu-moved
A    fu-moved/new-fu-file.c
Updated to revision 12.


# hey!  Mary's changes are not lost,
# but they are now unversioned and not in svn (still in fudir)
# and the fu-moved dir contains the new-fu-file.c version that was last seen by tom
# SO if they were part of many changes it would be easy to miss them
# the only clue to this problem is the "? fudir"

mary$ svn status -u
?                   fudir
Status against revision:     12

# The correct thing to do is for Mary to restore each of her changes by hand.
# Her svn status should as a general rule have the same number of Modified/Added/... files
#  before her checkin.
# She can copy in this case as there were no modifications to the file by Tom BUT
#  copying might be the wrong thing to do if there were changes.
#  (see svn manual Branching and Merging: Resurrecting Deleted Items)

mary$ cp fudir/new-fu-file.c fu-moved/

mary$ svn status -u
?                   fudir
M              12   fu-moved/new-fu-file.c
Status against revision:     13

mary$ svn ci -m"redo change to file after dir was moved"
Sending        trunk/fu-moved/new-fu-file.c
Transmitting file data .
Committed revision 14.


http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.ref.svn.c.status



I'm very surprised this move problem is not in the manual or FAQ (or is it?)
svn manual: svn.c.move  svn.c.merge svn.branchmerge
I think it is covered in the manual:
 svn manual Branching and Merging: Resurrecting Deleted Items

This issue is documented in the wikipedia: (Current issues)
http://en.wikipedia.org/wiki/Subversion_%28software%29
And in svn roadmap: http://subversion.tigris.org/roadmap.html
 http://subversion.tigris.org/issues/show_bug.cgi?id=898
I guess this problem isn't an issue really unless a lot of parallel development and
branch/merging is being done as we are doing.
Anyway, I'm surprised it isn't highlighted more.

Friday 22 June 2007

svn-follow-log.sh

Script to see svn branch log,
 and follow on from the log if earliest entry was a "rebranch",
 and keep on doing that until branch was really created.

Trac and mergebot very very useful for managing svn branches.
Manages making of branches and essentially  branch merges or rebranch very nicely.
 (works with branches with a parent branch too instead of trunk)

We seem to have been burnt by a big merge out on a branch.
Many revisions and a good few rebranches and merges back to parent.
So need to follow log revisions.

On command line svn log --stop-on-copy reports how to get "Previous log" revision. And now that I know what to look for I see a "Previous log" link in the trac log of any changeset which is a rebranch merge.

~/bin/svn-follow-log.sh
#!/bin/bash

if [[ "$1" == "" ]] ; then
  echo "usage: xt <ticket-nnn>"
  #TICKET=ticket-720
  exit
fi

TICKET=$1

touch ${TICKET}follow.log
BRANCHREV=quantiqa/branches/${TICKET}
SVNROOT=https://source.commprove.internal/repository

while [[ $BRANCHREV != "" ]] ; do
#echo go go go;
svn log  ${SVNROOT}/${BRANCHREV} --stop-on-copy >> ${TICKET}follow.log
BRANCHREV=`tail -2 ${TICKET}follow.log |grep "Previous log" | sed "s/.*log:\(.*\) Previous.*/\1/"`
echo $BRANCHREV
done;

http://trac.edgewall.org/

http://en.wikipedia.org/wiki/Subversion_(software)

Tuesday 19 June 2007

gnu compiler has things inside it

Coming to you from the land of gmake, ggrep, gegrep, gsed, gpwd, gcd, gcat, gdf, guname, ... gar, gld, gobjdump, (watch out gprof is often solaris gprof (in /usr/ccs/bin) ggprof is gnu gprof) ...  :)   i.e. solaris.

Watch out on solaris what linker is being used. And also watch out gcc libs may have internal library paths which can affect linking.

1. linker
 
gcc may be configured (at gcc compile time) to use gnu binutils or to use solaris linker/assembler. I would guess that the binutils might be more of a challenge to get working on solaris? Many (all?) sunfreeware packages of gcc use solaris linker/assembler. One difference noted is that solaris linker passes over libs just once by default. So library order is important and duplicates may have to be used (or else put "-Wl,-z,rescan" in LDFLAGS to pass to linker).  Another difference is different flags used to add to rpath at link time (-rpath for gnu ld, -R for solaris ld).

2. rpath in 64bit libs

/usr/sfw/lib contains 32bit libs, /usr/sfw/lib/64 contains 64bit libs.

But often the 64bit libgcc_s.so or 64bit libstdc++.so contain /usr/sfw/lib (32bit) in rpath.

This must be overridden using rpath in your own 64bit binary or using LD_LIBRARY_PATH in environment.


machine 1 (solaris 10, sparc):

gcc 4.1.1 configured with gnu binutils and gcc 3.4.3 from sunfreeware configured with solaris linker/assembler

$ /opt/GCC-SunOS-10-4.1.1/bin/g++ -print-prog-name=ld
/opt/GCC-SunOS-10-4.1.1/bin/ld

$ /usr/sfw/bin/g++ -print-prog-name=ld
/usr/ccs/bin/ld

$ /usr/sbin/pkgchk -l -p /usr/sfw/bin/g++
        SUNWgcc       


machine 2 (solaris 10, amd/x86):

both gcc 4.1.1 and gcc 3.4.3 from sunfreeware configured with solaris linker/assembler
$ /usr/sfw/bin/g++ -print-prog-name=ld
/usr/ccs/bin/ld

$ /opt/GCC-SunOS-10-4.1.1/bin/g++ -print-prog-name=ld
/usr/ccs/bin/ld

$ /usr/sbin/pkgchk -l -p /usr/sfw/bin/g++
        SUNWgcc


wacky:  64bit gcc libraries often have bad rpath in them  (see this 32bit lib rpath in the 64bit lib)
The runtime dynamic linker is happy to go with 32bit libs but of course it then has a problem loading them.
Interesting to note that the ld or gcc found in path affects the ldd -s output.

$ ldd -s /usr/sfw/lib/64/libstdc++.so

   find object=libm.so.2; required by /usr/sfw/lib/64/libstdc++.so
    search path=/usr/sfw/lib  (RPATH from file /usr/sfw/lib/64/libstdc++.so)
    trying path=/usr/sfw/lib/libm.so.2
    search path=/lib/64:/usr/lib/64:/opt/GCC-SunOS-10-4.1.1/lib/sparcv9  (configuration default - /var/ld/64/ld.config)
    trying path=/lib/64/libm.so.2
        libm.so.2 =>     /lib/64/libm.so.2

   find object=libgcc_s.so.1; required by /usr/sfw/lib/64/libstdc++.so
    search path=/usr/sfw/lib  (RPATH from file /usr/sfw/lib/64/libstdc++.so)
    trying path=/usr/sfw/lib/libgcc_s.so.1
    search path=/lib/64:/usr/lib/64:/opt/GCC-SunOS-10-4.1.1/lib/sparcv9  (configuration default - /var/ld/64/ld.config)
    trying path=/lib/64/libgcc_s.so.1
    trying path=/usr/lib/64/libgcc_s.so.1
    trying path=/opt/GCC-SunOS-10-4.1.1/lib/sparcv9/libgcc_s.so.1
        libgcc_s.so.1 =>         /opt/GCC-SunOS-10-4.1.1/lib/sparcv9/libgcc_s.so.1

   find object=libc.so.1; required by /usr/sfw/lib/64/libstdc++.so
    search path=/usr/sfw/lib  (RPATH from file /usr/sfw/lib/64/libstdc++.so)
    trying path=/usr/sfw/lib/libc.so.1
    search path=/lib/64:/usr/lib/64:/opt/GCC-SunOS-10-4.1.1/lib/sparcv9  (configuration default - /var/ld/64/ld.config)
    trying path=/lib/64/libc.so.1
        libc.so.1 =>     /lib/64/libc.so.1

   find object=libc.so.1; required by /lib/64/libm.so.2
    search path=/lib/64:/usr/lib/64:/opt/GCC-SunOS-10-4.1.1/lib/sparcv9  (configuration default - /var/ld/64/ld.config)
    trying path=/lib/64/libc.so.1

   find object=libc.so.1; required by /opt/GCC-SunOS-10-4.1.1/lib/sparcv9/libgcc_s.so.1
    search path=/lib/64:/usr/lib/64:/opt/GCC-SunOS-10-4.1.1/lib/sparcv9  (configuration default - /var/ld/64/ld.config)
    trying path=/lib/64/libc.so.1

   object=/lib/64/libc.so.1; filter for /usr/lib/sparcv9/ld.so.1

   object=/lib/64/libc.so.1; filter for libm.so.2

   find object=libm.so.2; required by /lib/64/libc.so.1
    search path=/lib/64:/usr/lib/64:/opt/GCC-SunOS-10-4.1.1/lib/sparcv9  (configuration default - /var/ld/64/ld.config)
    trying path=/lib/64/libm.so.2

   object=/lib/64/libc.so.1; filter for /platform/$PLATFORM/lib/sparcv9/libc_psr.so.1

   find object=/platform/SUNW,Sun-Fire-T200/lib/sparcv9/libc_psr.so.1; required by /lib/64/libc.so.1
        /platform/SUNW,Sun-Fire-T200/lib/sparcv9/libc_psr.so.1

Thursday 14 June 2007

C++ using templatised params in typedef and general struggling

Trying to do something completely perfectly in C++ but it's becoming an epic struggle. Templatised things must be kept in a list, processed by template class (invoked two different threads). But the templatisation must be exposed to interface in and out of class.

Just one of numerous problems seem to be with a typedef of a hash map of templatised types ...  The kind of typedef used here works if the HashMap params aren't templatised params. I might be missing some relatively basic C++ template knowledge or, well the why doesn't it just do what I mean! :'(

template<typename QIdType, typename SeqType>
class CRetxLink
{

   typedef struct retx_data
   ...
      SeqType                    m_retx_seq_no;
   ...
   } retx_data_t;

typedef dts::HashMap<QIdType, retx_data_t*> HashTypeData;
boost::shared_ptr<HashTypeData> p_retx_list;

// compiler doesn't like this:
HashTypeData::iterator iterData = p_retx_list->begin();


// e.g. this is okay outside of class
typedef struct retx_data
   ...
      unsigned int                    m_retx_seq_no;
   ...
   } retx_data_t;

typedef dts::HashMap<unsigned int, retx_data_t*> HashTypeData;


Need to go back and start with the basics again .....


// essentially a generic interface to the templatized classes would be a start.

#include <string>
#include <iostream>

//g++ ~/c/templateInterface.cpp -o ~/c/templateInterface

class CTempInterface
{
public:
CTempInterface()
{
};

~CTempInterface()
{
};

virtual void Method()
{
printf("Method %s\n", __FUNCTION__);
}

};

template<typename T>
class TTemp : public CTempInterface
{
public:
TTemp()
{
};

~TTemp()
{
};

void Method()
{
printf("Method %s\n", __FUNCTION__);
std::cout << "two: " << thingywotsit << "\n";
}

T thingywotsit;

};


int main()
{
TTemp<int> tt_i;
TTemp<std::string> tt_s;

//TTemp &p;
CTempInterface *p;

p = &tt_i;
p->Method();

p = &tt_s;
p->Method();
}

Thursday 7 June 2007

geek soul forfeit?

/me forfeits geek soul
messaging while slightly drunk
ohhh! svn ci while slightly drunk! >;)
editing /etc/sysconfig/ stuff too
whee.

it wasn't me by the way. it was the piano
and slightly is < a can of guinness
but it seems to be working very well.
so I said what else can I do ... ahh yes. blog while slightly drunk.

oh great. my amazing powers of software breaking manifest themselves.  can't post ... ???
Hmmm. methinks livejournal doesn't like being kindof logged in in multiple tabs?
Anyone else find the same?

Friday 1 June 2007

use libumem to make a memory use profile

Solaris 9/10 though we note libumem is being ported to linux.
 https://labs.omniti.com/trac/portableumem


1. run binary with libumem debug

   UMEM_DEBUG=default UMEM_LOGGING=transaction LD_PRELOAD=libumem.so.1 <binary file and params>

2. gcore and run mdb on it

   gcore -o myumemcore -p <pid>

3. run mdb commands on core file (step can take a while depending on core size)

   mdb <binary file> myumemcore <umem-test.mdb

less umem-test.mdb    
 $c !tee>>umem.log
 ::walk thread |::findstack !tee>>umem.log

 ::umastat !tee>>umem.log
 ::umem_status !tee>>umem.log
 ::umem_verify !tee>>umem.log
 ::umalog !tee>>umem-umalog.log
 
 ::findleaks !tee>>umem-leaks.log

 ::umausers !tee>umem-umausers.log
 *umem_oversize_arena::walk vmem_alloc | ::vmem_seg -v !tee>umem-oversize.log

 $q


4. Generate simple list of:

bytes  allocation-count  block-size   stack-reference(1st line that is not libumem malloc or libstdc++ new)

#!/bin/bash
# allow over-ride from environment
[[ $UMEMOVER == "" ]] && export UMEMOVER=umem-oversize.log;
[[ $UMEMUSER == "" ]] && export UMEMUSER=umem-umausers.log

UMEMPROFILE1=umem-profile1.log
UMEMPROFILE=umem-profile.log

egrep -v "(ADDR TYPE|THREAD *TIMESTAMP)" $UMEMOVER | perl -00 -pe '$foo = $_; ($ptr,$size,$thread_and_ts,$rest) = m/^\s*(\w+)\s+\w+\s+\w+\s+\w+\s+(\w+)\s*\n(.*)\n([\w\W]*)$/m; print "ptr: $ptr size: $size "; $rest =~ s/libumem.*/URK/g; $rest =~ s/libstd.*_Zn[wa]m.*/CURK/g; $_ = $rest; ($stackref) = m/\s*[CURK\s\W]+\s+(\S+)\s+/m; print "stackref: $stackref\n"; $_="";'  |sed "s/.*size: \(.*\) stackref: /\1 /" |sort |uniq -c |sed "s/  */ /g; s/^ *//" |perl -pe '$foo = $_; ($allocs,$blocksize,$rest) = m/^\s*(\w+)\s+(\w+)\s+(.*)$/; print ($allocs*$blocksize); print " ";' >$UMEMPROFILE

cat $UMEMUSER |gegrep -v "^ *(libumem|libstdc++)" |ggrep -A1 "bytes for" |sed  "s/\-\-//" |perl -00 -pe '$foo = $_; ($bytes,$allocs,$block,$rest) = m/^\s*(\w+)\s+bytes for\s+(\w+)\s+allocations with data size (\w+):\s*\n(.*)$/m; print "$bytes $allocs $block "; $rest =~ s/libumem.*/URK/g; $rest =~ s/libstd.*_Zn[wa]m.*/CURK/g; $_ = $rest; ($stackref) = m/\s*[CURK\s\W]+\s+(\S+)\s+/m; print "$rest\n"; $_="";' >> $UMEMPROFILE1

sort -n $UMEMPROFILE1 |perl -pe 'BEGIN{$tot=0; print "Bytes Allocations Block-size Stackref";} $foo = $_; ($bytes,$allocs,$blocksize,$rest) = m/^\s*(\w+)\s+(\w+)\s+(\w+)\s+(.*)$/; $tot+=$bytes; END{print "Total bytes: $tot\n";}' |tee $UMEMPROFILE



Hmmm. Maybe I should have just done it in perl.

more bash and subversion ignores

# allow over-ride NORMAL_EXTNS in environment if script being called by a robot.
if [[ $NORMAL_EXTNS == "" ]] ; then
    NORMAL_EXTNS="bash|bat|bmp|c|cc|cfg|cgi|cmd|conf|config|cpp|dll|doc|exp|gif|gnuplot|footer|h|hpp|html|ico|java|jpeg|jpg|pdf|php|pl|png|ppt|py|rc|rc2|sh|txt|vcproj|vsprops|wsdl|xls|xml"
fi


IGNORES=`svn status |grep ^? |egrep -v "\.($NORMAL_EXTNS)$" |sed "s/\?  *//;
  s/\(\.host\.make\.\).*/\1\\\\\*/;
  s/\([^\/][^\/]*\)\.\([^.*\/]*\)$/\\\\\*\.\2/;
  " |sort |uniq`



# get list of extensions under source control
EXTNS=`svn status -v |grep -v ^? |grep "\.[^\s]" |sed "s/.*\.\([^.][^.]*\)$/\1/" |sort |uniq `
# This line is quite useful making content for the NORMAL_EXTNS line above

NOT_IN_NORMAL=""
for ext in $EXTNS ; do
   NOT_IN_NORMAL="$NOT_IN_NORMAL `echo ".$ext" |egrep -v "\.($NORMAL_EXTNS)$"`" ;
done
# remove whitespace
NOT_IN_NORMAL=`echo $NOT_IN_NORMAL`
if [[ $NOT_IN_NORMAL != "" ]] ; then
   echo \# extensions with ignore, but not \"normal\" ignore:
   echo \# consider update of NORMAL_EXTNS= line in `basename $0`
   echo $NOT_IN_NORMAL
fi

Pirate costume

After cubs last night and after collecting rest of gear needed for Daire's camping trip we started on pirate costume.

Bandana for head (stripey silk hanky)
Two of my shirts :- white one underneath with cloth belt around waist and sleeves rolled up and blue shirt over that looks like a coat.
Sports socks with trousers tucked in and pushed up to knee.
Sword with hand guard: bamboo stick sprayed with silver paint and cardboard/duct-tape guard.

Daire has good sword technique gleaned from the Princess Bride (and not Pirates of the Caribbean he says).

Julie's French Apple Cake

Last ditch effort late last night recipes for dspsrv cookbook.

Julie's French Apple Cake

from:
Annabel Karmel's Quick Children's Meals
http://www.amazon.co.uk/Annabel-Karmels-Quick-Childrens-Meals/dp/0091851890


Implements:

   rubber baking "tin"
   mixing bowl

Ingredients:

   5 small eating apples (or less bigger ones in quarters)
   1 lemon
   butter - 7oz (200g) *warm it up*
   brown sugar - 8oz (225g) (see note)
   4 eggses
   plain flour  - 7oz (200g)
   baking powder - 1 tsp
   dessicated coconut - 4oz (100g)

   note: actually caster sugar in book but Cranks' is right.
       Less refined ingredients do taste better.

   Peel & core apples, cut in half (or quarters) and squeese lemon juice over.
   Score the round side of the apples.

   Beat butter and sugar then add eggs one by one.
   Mix in flour, baking powder and 70g of the coconut.

   Grease cake tin. If it is not of the non-stick rubber type then grease it
   very well and line with greaseproof paper. Cake is very sticky.

   Pour mix into tin.
   Arrange apples in circle or regular design, curved side up and press
   down until just about covered.
   Sprinkle rest of coconut over top.

   Bake in oven at 170C/325F/Fas 3 for 50 minutes.


--------------------------------------------------------------------------------

Home made burgers (or meatballs)


A little messy but easy and yummy. Very nice with a sauce.

If you make spheres instead of burger shapes you can call them meatballs.
Putting jar of tomato stuff over them and baking works very well.

Implements:

   mixing bowl
   knife & chopping board

Ingredients:

   mince - beef/lamb
   Some slices of bread (for breadcrumbs - stale is arguably better)
   onion
   garlic (optional)
   salt/pepper
   chopped herbs
   egg
   flour (for dusting - optional)


   You can buzz up bread in a buzzer to make breadcrumbs.
   Or tear it into small bits by hand into a mixing bowl and then pick up
   the bits and roll them between your fingers/hands.
   Cold toast smashes up easily.

   Chop up onion and garlic very small.

   Get tray ready for holding burgers.

   Roll up sleeves. Your hands are going to get messy.

   Mix everything together in bowl (except flour).
   Use your hands to mix.
   Now take a small fist of the mix and squash it and pass from
   hand to hand and form into a UFO shape.

   Fry or grill burgers.

   Serve with some sauce and maybe veg and carbohydrate.


--------------------------------------------------------------------------------
Cranks' nut loaf

Very yummy with grated cheese and a tomato sauce. And fried onions.
See tomato sauce recipe below but we use jars of bought sauce most often.

Implements:

   buzzer capable of chopping nuts
   baking tin - loaf type.

Ingredients:

   onion - 1 medium, I prefer more and some garlic.
   butter or margarine - 1 knob
   mixed nuts (peanuts, walnuts, cashews, ...) - 8oz (225g)
   wholemeal bread - 4oz (100g)
   vegetable stock or water .5 pt (300ml)
   yeast extract - 2 tsp (10ml)  ! yes I know. see note.
   mixed herbs
   salt & pepper

note: yeast extract = marmite!
It took me a few years to figure that out.

   Chop onions small.
   Saute onions gently in butter.

   Chop nuts & bread in buzzer. Until quite fine.

   Heat stock and yeast extract to boiling point.

   Grease baking tin.

   Mix everything together and put into the tin.
   Sprinkle some breadcrumbs on top.

   Bake in oven at 180C/350F/mark 4 for 30 minutes.




Cranks' tomato sauce


Goes great with lots of things.
Like stew/soup tastes better the next day.

Ingredients:

   onion - 1 medium
   garlic
   tomatoes - 12oz (350g)   (maybe tinned tomatoes okay)
   butter or margarine - 1 knob
   vegetable stock or water .5 pt (300ml)
   tomato puree
   basil (or other herbs)
   salt & pepper

   Maybe a little sugar or actually carrot chopped up very small adds
   natural sweetness which the tomatoes need.


   Chop onion and tomatoes. (and carrot very small if using)
   Saute onions (and maybe carrot) gently in butter.
   Add everything else, bring to boil then simmer uncovered for 20 mins.

Irish weather

On the best days we get bright sunshine alternating with dark clouds and rain from light drizzle to heavy showers. The wind will do funny things. Rainbows and hail/snow if it's being especially exciting.

http://www.dspsrv.com/~jamesc