tcm-2.20+TSQD.orig/0000755000175000017500000000000010100221227014535 5ustar otaviootavio00000000000000tcm-2.20+TSQD.orig/bin/0000755000175000017500000000000010100220655015311 5ustar otaviootavio00000000000000tcm-2.20+TSQD.orig/bin/makeundepend.sh0000755000175000017500000000140610077527116020330 0ustar otaviootavio00000000000000#!/bin/sh # # makeundepend.sh # copyright (c) 2001 Henk R. van de Zandschulp, David N. Jansen # $Id: makeundepend.sh,v 1.2 2002/05/29 08:27:34 henkz Exp $ # makefile= [ -f makefile ] && makefile=makefile [ -f Makefile ] && makefile=Makefile [ -f GNUMakefile ] && makefile=GNUMakefile [ ${makefile} ] || { echo cannot find a makefile ... bailing out exit 1 } marker='# DO NOT DELETE THIS LINE -- make depend depends on it.' grep "${marker}" ${makefile} >/dev/null 2>&1 [ $? -eq 0 ] && foundit=y || foundit= if [ ${foundit} ] ; then /bin/rm -f ${makefile}.bak mv ${makefile} ${makefile}.bak sed -e "/${marker}/q" < ${makefile}.bak > ${makefile} || { echo sed command failed ... bailing out exit 1 } fi # [ ${foundit} ] # EOF tcm-2.20+TSQD.orig/bin/Makefile0000755000175000017500000000060110077527116016770 0ustar otaviootavio00000000000000TCM_INSTALL_BIN=$(TCM_INSTALL_DIR)/bin all: config: install: @if test $(TCM_COMPILER) = gcc; then\ TCM_HOME=$(TCM_HOME) ./linkx; fi if test ! -d $(TCM_INSTALL_BIN); then\ mkdir -p $(TCM_INSTALL_BIN);\ $(CHMOD) 755 $(TCM_INSTALL_BIN); \ fi $(TCM_INSTALL_CMD) psf t* $(TCM_INSTALL_BIN) clean: $(RM) t* c* -include $(TCM_HOME)/src/Config.tmpl tcm-2.20+TSQD.orig/bin/linkx0000755000175000017500000000136510077530070016401 0ustar otaviootavio00000000000000#!/bin/sh [ ${TCM_HOME} ] || { echo TCM_HOME is not set. Bailing out.; exit 1 } cd $TCM_HOME/bin DFILES="tgd terd tesd tcrd tssd tsqd tucd tatd tstd trpg tpsd tdfd tefd tsnd tgtt tfrt tcpd tdpd tcbd tscd" TFILES="tgt ttut ttdt tfet" # remove TCM tool executables and make softlinks # to the tcmd.exe and tcmt programs. rm -f $TFILES $DFILES ## sed removes the NT-version in Cygwin ARCH=`uname -s | sed -e 's/_NT.*//'` for X in $DFILES ; do if [ "x$ARCH" = "xCYGWIN" ] ; then c="$TCM_HOME/bin/_cygwin_symlink.sh tcmd.exe ${X}.exe" echo $c sh $c else ln -s tcmd $X fi done for X in $TFILES ; do if [ "x$ARCH" = "xCYGWIN" ] ; then c="$TCM_HOME/bin/_cygwin_symlink.sh tcmt.exe ${X}.exe" echo $c sh $c else ln -s tcmt $X fi done tcm-2.20+TSQD.orig/bin/mkclasslist0000755000175000017500000000041310077527116017605 0ustar otaviootavio00000000000000#!/bin/sh # make a list of header file path names sorted on file name. [ ${TCM_HOME} ] || { echo TCM_HOME is not set. Bailing out.; exit 1 } find $TCM_HOME/src -type f -name '*.h' -print | awk -F'/' '{printf("%s %s\n", $0, $NF)}' | sort +1 -2 | awk '{print $1}' tcm-2.20+TSQD.orig/bin/_cygwin_chmodplusx.sh0000755000175000017500000000026210077527116021574 0ustar otaviootavio00000000000000#!/bin/sh ## ## Daniel Boesswetter ## ## Fri Oct 25 13:11:40 2002 ## if [ -e "$1.exe" ]; then n=$1.exe else n=$1 fi setfacl.exe -m user::rwx $n tcm-2.20+TSQD.orig/bin/linky0000755000175000017500000000320610077530112016373 0ustar otaviootavio00000000000000#!/bin/sh [ ${TCM_HOME} ] || { echo TCM_HOME is not set. Bailing out.; exit 1 } cd $TCM_HOME/bin GDFILES="tgd" DVFILES="terd tesd tcrd tssd tucd tcbd tsqd" BVFILES="tatd tstd trpg tpsd tscd" FVFILES="tdfd tefd tsnd" TRILES="tgtt tfrt" PVILES="tcpd tdpd " TFILES="tgt ttut ttdt tfet" # remove TCM tool executables and make softlinks # to the tcm?? executables. rm -f $GDFILES $DVFILES $BVFILES $FVFILES $PVILES $TRILES $TFILES ## sed removes the NT-version in Cygwin ARCH=`uname -s | sed -e 's/_NT.*//'` for X in $GDFILES ; do if [ "x$ARCH" = "xCYGWIN" ] ; then c="$TCM_HOME/bin/_cygwin_symlink.sh tcmgd.exe ${X}.exe" echo $c $c else ln -s tcmgd $X fi done for X in $DVFILES ; do if [ "x$ARCH" = "xCYGWIN" ] ; then c="$TCM_HOME/bin/_cygwin_symlink.sh tcmdv.exe ${X}.exe" echo $c $c else ln -s tcmdv $X fi done for X in $BVFILES ; do if [ "x$ARCH" = "xCYGWIN" ] ; then c="$TCM_HOME/bin/_cygwin_symlink.sh tcmbv.exe ${X}.exe" echo $c $c else ln -s tcmbv $X fi done for X in $FVFILES ; do if [ "x$ARCH" = "xCYGWIN" ] ; then c="$TCM_HOME/bin/_cygwin_symlink.sh tcmfv.exe ${X}.exe" echo $c $c else ln -s tcmfv $X fi done for X in $TRFILES ; do if [ "x$ARCH" = "xCYGWIN" ] ; then c="$TCM_HOME/bin/_cygwin_symlink.sh tcmtr.exe ${X}.exe" echo $c $c else ln -s tcmtr $X fi done for X in $PVFILES ; do if [ "x$ARCH" = "xCYGWIN" ] ; then c="$TCM_HOME/bin/_cygwin_symlink.sh tcmpv.exe ${X}.exe" echo $c $c else ln -s tcmpv $X fi done for X in $TFILES ; do if [ "x$ARCH" = "xCYGWIN" ] ; then c="$TCM_HOME/bin/_cygwin_symlink.sh tcmt.exe ${X}.exe" echo $c $c else ln -s tcmt $X fi done tcm-2.20+TSQD.orig/bin/_cygwin_symlink.sh0000755000175000017500000000035010077527116021072 0ustar otaviootavio00000000000000#!/bin/sh ## ## Daniel Boesswetter ## ## Fri Oct 25 11:03:05 2002 ## ## wrapper for "ln -s" that also copies the acl (non-default on cygwin) ## c="ln -s $1 $2" echo $c $c getfacl $1 | setfacl -f - $2 tcm-2.20+TSQD.orig/bin/psf0000755000175000017500000004630510077527116016056 0ustar otaviootavio00000000000000#!/usr/bin/perl # $Header: /home/maics/tcm/cvsroot_DEV/tcm/bin/psf,v 1.1.1.1 2001/10/06 21:10:55 tcm Exp $ # states: # 1 HeaderComment # 2 HeaderBody # 3 PageComments # 4 PageBody # 5 Trailer eval "exec /usr/bin/perl -S $0 $*" if $running_under_some_shell; # this emulates #! processing on NIH machines. # (remove #! line above if indigestible) $, = ' '; # set output field separator $\ = "\n"; # set output record separator sub handler { # 1st argument is signal name local($sig)= @_ ; if ( $reverse ) { for ( $i=$pagecount ; $i>=1 ; $i-- ) { unlink "$tmphead$$.$i" ; } } } sub protect_string { # convert a string into PostScrip accepted form local($result) = @_ ; $result =~ s/\\/\\\\/g ; $result =~ s/\(/\\(/g ; $result =~ s/\)/\\)/g ; $result =~ s/ /\\t/g ; $result =~ s/\n/\\\\n/g ; $result; } sub start_page { # Start a page of output $pagecount++ ; if ( $reverse ) { if ( ! open( tmpfile, ">$tmphead$$.$pagecount" ) ) { print stderr 'psf: cannot create temporary file '. "$tmphead$$.$pagecount" ; exit 9 ; } $OUTPUT= 'tmpfile' ; } } sub phe { #!!Eophtrans'; /* End of Page Header Comments */ if ( $land || $upside ) { print $OUTPUT '%%BeginPageSetup' ; printf $OUTPUT "gsave %g rotate %g %g translate\n", $rotate_value, $x_shift, $y_shift ; print $OUTPUT '%%EndPageSetup' ; } } sub eop { #!!Eop'; /* End of previous Page */ if ( $land || $upside ) { print $OUTPUT '%%PageTrailer' ; print $OUTPUT 'grestore' ; } if ( $twoinone ) { print $OUTPUT '%%EndDocument' ; if ( $twofirst ) { $twofirst=0 ; } else { $twofirst=1 ; print $OUTPUT $p_encaps_e . 'restore showpage' ; } } } sub eoh { if ( $eoh_done ) { return ; } $eoh_done=1 ; #!!Eoh'; /* Just before the first %%Page or %%Trailer */ if ( !$early_device_done ) { do early_device() ; } if ( $copies>1 ) { if ( $copies>100 ) { print stderr 'psf: Sorry, we will not print that many'; } else { if ( ! $started_setup ) { $started_setup=1 ; print $OUTPUT '%%BeginSetup' ; } print $OUTPUT '/#copies ' . ($copies+0) . " def" ; } } if ( $set_security ) { if ( ! $started_setup ) { $started_setup=1 ; print $OUTPUT '%%BeginSetup' ; } @Fld=split(',',$passwd); if ( $#Fld>1 ) { $passwd=$Fld[1] ; $sec_mess=$Fld[2] ; } $numval= $passwd+0 ; if ( $numval ne $passwd || $numval<0 || $numval>99999999 ) { print stderr "psf: the security string must be a number between 0 and 99999999" ; exit 8 ; } $sec_mess= &protect_string($sec_mess) ; print $OUTPUT '/statusdict where' . ' { pop statusdict dup begin ' . "/checksecurity known {($passwd) ($sec_mess) checksecurity} if ". 'end} if' ; } if ( $manfeed>0 ) { if ( ! $started_setup ) { $started_setup=1 ; print $OUTPUT '%%BeginSetup' ; } print $OUTPUT '/statusdict where' . ' { pop statusdict dup begin ' . 'dup /manualfeed known {/manualfeed true def} if ' . '/setpapertray known {1 setpapertray} if ' . 'end} if' ; } if ( $set_inputtray ) { if ( ! $started_setup ) { $started_setup=1 ; print $OUTPUT '%%BeginSetup' ; } if ( $manfeed ) { print stderr "the -m and -inputtray options conflict" ; } print $OUTPUT '/statusdict where' . ' { pop statusdict dup begin ' . "/setpapertray known {$inputtray setpapertray} if ". 'end} if' ; } if ( $transparency ) { if ( ! $started_setup ) { $started_setup=1 ; print $OUTPUT '%%BeginSetup' ; } print $OUTPUT "<< /MediaType (Transparency) >> setpagedevice"; } if ( $set_sort ) { if ( ! $started_setup ) { $started_setup=1 ; print $OUTPUT '%%BeginSetup' ; } # The specified output tray is used as the bin to start sorting in. # If no outputtray is given, logical bin 1 is used. if ( $set_outputtray ) { $set_outputtray=0 ; } else { $outputtray=2 ; } if ( $sort_param == -1 ) { if ( $copies==0 ) { $sort_copies=20 ; } else { $sort_copies=$copies ; } } else { $sort_copies=$sort_param ; } $endtray= $outputtray + $sort_copies -1 ; print $OUTPUT '/statusdict where' . ' { pop statusdict dup begin ' . "/sortmethod known {1 $outputtray $endtray sortmethod} if ". 'end} if' ; } if ( $set_outputtray ) { if ( ! $started_setup ) { $started_setup=1 ; print $OUTPUT '%%BeginSetup' ; } print $OUTPUT '/statusdict where' . ' { pop statusdict dup begin ' . "/setoutputtray known {$outputtray setoutputtray} if ". 'end} if' ; } if ( $set_select ) { if ( ! $started_setup ) { $started_setup=1 ; print $OUTPUT '%%BeginSetup' ; } print $OUTPUT '/statusdict where' . ' { pop statusdict begin true} {false} ifelse' ; print $OUTPUT '10 dict begin /psf-s-count count def ' . '/psf-d-count countdictstack 1 add def' ; print $OUTPUT "{ $select_string } stopped" ; print $OUTPUT 'countdictstack -1 psf-d-count {pop end} for ' . 'count -1 psf-s-count {pop exch pop} for' ; print $OUTPUT 'end { end } if' ; } if ( $land || $twoinone ) { # reverse the tumble operation for landscape and -2 mode if ( $tumble eq 'true' ) { $tumble='false' ; } else { $tumble='true' ; } } if ( $set_duplex ) { if ( ! $started_setup ) { $started_setup=1 ; print $OUTPUT '%%BeginSetup' ; } print $OUTPUT '/statusdict where' . ' { pop statusdict dup begin ' . ($duplex eq 'true' ? "dup\n" : "\n" ) . "/setduplexmode known {$duplex setduplexmode} if\n". ($duplex eq 'true' ? "/settumble known {$tumble settumble} if ": '' ). 'end} if' ; } elsif ( $set_tumble ) { if ( ! $started_setup ) { $started_setup=1 ; print $OUTPUT '%%BeginSetup' ; } print $OUTPUT '/statusdict where' . ' { pop statusdict dup begin ' . "/settumble known {$tumble settumble} if ". 'end} if' ; } if ( $started_setup ) { print $OUTPUT '%%EndSetup' ; } } sub early_device { local($comment_opened) = 0 ; if ( !$early_device_done ) { $early_device_done=1 ; if ( $ips != -1 ) { if ( !$comment_opened ) { print $OUTPUT '%%BeginSetup' ; } $comment_opened= 1 ; print $OUTPUT "<< /Policies << /PageSize $ips >> >> setpagedevice"; } if ( $noreport != 0 ) { if ( !$comment_opened ) { print $OUTPUT '%%BeginSetup' ; } $comment_opened= 1 ; print $OUTPUT "<< /Policies << /PolicyReport { pop } >> >> setpagedevice"; } if ( $comment_opened ) { print $OUTPUT '%%EndSetup' ; } } } sub trailpages { if ( $pages_done==0 ) { print $OUTPUT '%%Pages: '. $pagecount . ' ' . $pageorder ; $pages_done=1 ; } } sub trailbb { if ( $bb_done==0 ) { $bb_comment= $file_bb ; do out_bb() ; $bb_done=1 ; } } sub det_new_corner { $mapped_x= $cos_val * $_[1] - $sin_val * $_[2] ; $mapped_y= $sin_val * $_[1] + $cos_val * $_[2] ; if ( $mapped_x < $new_bb_llx ) { $new_bb_llx = $mapped_x ; } if ( $mapped_x > $new_bb_urx ) { $new_bb_urx = $mapped_x ; } if ( $mapped_y < $new_bb_lly ) { $new_bb_lly = $mapped_y ; } if ( $mapped_y > $new_bb_ury ) { $new_bb_ury = $mapped_y ; } } sub upper_int { ( $_[1]<0 ? int $_[1] : int ($_[1] + 0.99999) ) ; } sub lower_int { ( $_[1]<0 ? int ($_[1] - 0.99999) : int $_[1] ) ; } sub mod_bb { # The -2 option simply assumes unchanged bounding boxes @Fld=split(' ',$bb_comment); $Pi= 2*atan2(1,0) ; $bb_llx= $Fld[2] ; $bb_lly=$Fld[3] ; $bb_urx= $Fld[4] ; $bb_ury=$Fld[5] ; $bb_llx += $x_shift ; $bb_lly += $y_shift ; $bb_urx += $x_shift ; $bb_ury += $y_shift ; $cos_val= cos( ($rotate_value/360)*2*$Pi) ; $sin_val= sin( ($rotate_value/360)*2*$Pi) ; # rotate each corner and determine max/min values $new_bb_llx= $cos_val * $bb_llx - $sin_val * $bb_lly ; $new_bb_lly= $sin_val * $bb_llx + $cos_val * $bb_lly ; $new_bb_urx= $new_bb_llx ; $new_bb_ury= $new_bb_lly ; do det_new_corner($bb_urx,$bb_lly) ; do det_new_corner($bb_urx,$bb_ury) ; do det_new_corner($bb_llx,$bb_ury) ; # $new_bb_llx += $x_shift ; $new_bb_lly += $y_shift ; # $new_bb_urx += $x_shift ; $new_bb_ury += $y_shift ; print $OUTPUT $Fld[1], &lower_int($new_bb_llx), &lower_int($new_bb_lly), &upper_int($new_bb_urx), &upper_int($new_bb_ury) ; } sub out_bb { if ( $land || $upside || $twoinone ) { if ( $doubles && !( $state==1 || $state==3) ) { print $OUTPUT $bb_comment; } do mod_bb() ; } else { print $OUTPUT $bb_comment; } } $tumble='false' ; # default tumble mode for duplex printing $login = getlogin || (getpwuid($<))[0] || $ENV{'LOGNAME'} ; if ( $login eq '' ) { $login= "Somebody"; } $sec_mess=$login ; $ips= -1 ; argloop: while($_=$ARGV[0],/^-/){ # When you add options here: do not forget the check at the END!! last if /^-$/; shift ; last if /^--$/; if ( /^-outputtray(.*)/ ) { $set_outputtray=1 ; $outputtray= ($1 eq "" ? ($ARGV[0],shift) : $1) ; next argloop ; } if ( /^-o(.*)/ ) { $orange= ($1 eq"" ? ($ARGV[0],shift) : $1); next argloop ; } if ( /^-#(.*)/ ) { $copies= ($1 eq"" ? ($ARGV[0],shift) : $1) ; next argloop ; } if ( /^-courierold$/ ) { $courierold=1 ; next argloop ; } if ( /^-c$/ ) { $manfeed=1 ; next argloop ; } if ( /^-p$/ ) { $printit=1 ; next argloop ; } if ( /^-r$/ ) { $reverse=1 ; next argloop ; } if ( /^-land$/ ) { $land=1 ; next argloop ; } if ( /^-2$/ ) { $twoinone=1 ; next argloop ; } if ( /^-upside/ ) { $upside=1 ; next argloop ; } if ( /^-transparency/ ) { $transparency=1 ; next argloop ; } if ( /^-b(.*)/ ) { $letter=($1 eq"" ? 'vu' : $1); next argloop ; } if ( /^-inputtray(.*)/ ) { $set_inputtray=1 ; $inputtray= ($1 eq"" ? ($ARGV[0],shift) : $1) ; next argloop ; } if ( /^-select/ ) { $set_select=1 ; $select_string= $ARGV[0],shift ; next argloop ; } if ( /^-duplex/ ) { $set_duplex=1 ; $duplex='true' ; next argloop ; } if ( /^-noduplex/ ) { $set_duplex=1 ; $duplex='false' ; next argloop ; } if ( /^-tumble/ ) { $set_tumble=1 ; $tumble='true' ; next argloop ; } if ( /^-sort(.*)/ ) { $set_sort=1 ; $sort_param= ($1 eq"" ? -1 : $1); next argloop ; } if ( /^-security(.*)/ ) { $set_security=1 ; $passwd= ($1 eq "" ? ($ARGV[0],shift): $1 ); next argloop ; } if ( /^-nondsc/ ) { $nondsc=1 ; next argloop ; } if ( /^-ips_error/ ) { if ( $ips != -1 ) { print stderr "warning; two ips options" ; } $ips=0 ; next argloop ; } if ( /^-ips_ignore/ ) { if ( $ips != -1 ) { print stderr "warning; two ips options" ; } $ips=1 ; next argloop ; } if ( /^-ips_fit/ ) { if ( $ips != -1 ) { print stderr "warning; two ips options" ; } $ips=3 ; next argloop ; } if ( /^-noreport/ ) { $noreport=1 ; next argloop ; } if ( /^-m(.*)/ ) { $m=1 ; ($1 eq"" ? ($message= $ARGV[0],shift) : ($message=$1)); $message =~ s/[\\\(\)]/\\$&/g ; next argloop ; } print stderr "psf: unknown argument \"$_\", ignored" ; } $[ = 1; # set array base to 1 if ( $orange ne "" ) { @r1= split( /,/, $orange ) ; $rangecount=1 ; for( @r1 ) { $startp[$rangecount]= $_ ; $endp[$rangecount]= $_ ; /(.*)-(.*)/ && ( $startp[$rangecount] = ( $1 ne "" ? $1 : -1) , $endp[$rangecount]= ( $2 ne "" ? $2 : 32767) ) ; $rangecount++ ; } } $doubles = 0 ; # Allow double comments $state = 1; # /* Header comment */ $pages_seen=0; # %%Pages seen $bb_seen =0; # %%BoundingBox seen $printing = 1; $doccount = 0; $change_pages = ( $orange ne "" || $twoinone ) ? 1 : 0 ; $change_bb = $land || $upside ; $pagecount=0 ; $OUTPUT= 'stdout' ; $tmphead= '/usr/tmp/psf.' ; $libhead= '/usr/local/lib/ProcSets' ; $twofirst= 1 ; # The first of two pages $page_length = 11.7 ; # Page length in inches $page_width = 8.2755 ; # Page width # The two strings used below may be empty on `wise' machines $p_encaps_b = '100 dict begin /TwoState exch def ' ; $p_encaps_e = 'TwoState end ' ; if ( $land || $upside ) { if ( $land ) { if ( $upside ) { $rotate_value= -90 ; $x_shift= - $page_width * 72 ; $y_shift= 0 ; } else { $rotate_value= 90 ; $x_shift= 0 ; $y_shift= -$page_length * 72 ; } } else { $rotate_value= 180 ; $x_shift= - $page_width * 72 ; $y_shift= -$page_length * 72 ; } } if ( $reverse ) { $SIG{'INT'}='handler'; $SIG{'QUIT'}='handler'; $SIG{'TERM'}='handler'; $SIG{'HUP'}='handler'; } if ( $printit ) { $infeed[1]= 'psprint '. join(' ',@ARGV) . ' |' ; } else { if ( $#ARGV<$[ ) { $infeed[1]=('-'); } else { @infeed= @ARGV ; } } while ($argument= shift infeed ) { if ( ! open(INPUT,$argument) ) { print stderr 'psf: cannot open "' . $argument . '"' ; next ; } line: while() { chop; # strip record separator if ($doccount > 0) { if (/^%%BeginDocument/) { $doccount++; } if (/^%%EndDocument/) { $doccount--; } if ($printing) { print $OUTPUT $_; } next line; } if ($. == 1 && !/^%!PS-Adobe-/) { print stderr 'psf: Warning, the input is not structured'; } if (/^%!/) { if ($printing) { print $OUTPUT $_; } next line; } if ($state == 1 && $change_pages && $pages_seen==0 && /^%%Pages:/ ) { $pages_seen=1 ; print $OUTPUT '%%Pages: (atend)'; $pages_at_trail=1 ; /%%Pages: \(atend\)/ && (next line) ; /%%Pages: *[^ ]* *(.*)/ && ($pageorder=$1) ; if ( $doubles ) { print $OUTPUT $_; } next line; } if ($state == 1 && $change_bb && $bb_seen==0 && /^%%BoundingBox:/ ) { $bb_seen=1 ; if ( /^%%BoundingBox: \(atend\)/ ) { $bb_at_trail=1 ; print $OUTPUT $_; next line ; } $bb_comment= $_ ; $file_bb=$_ ; do out_bb() ; next line ; } if ($state == 1 && (!/^%%/ || /^%%EndComments/)) { $thisline=$_ ; if (!/^%%EndComments/) { print $OUTPUT '%%EndComments'; } else { print $OUTPUT $_; } $state = 2; # /* Header Body */ if ( $courierold ) { # use setcourierold after first comment print $OUTPUT '%%BeginStrange' ; print $OUTPUT '{ setcourierold } stopped pop' ; print $OUTPUT '%%EndStrange' ; } if ( !$early_device_done ) { do early_device() ; } if ( $nondsc ) { do eoh() ; } if ( $letter ) { # We should add Helvetica-Bold to document fonts and # add the ProcSet to DocumentSuppliedProcSets if ( ! open ( tmpfile, "$libhead/$letter" . 'let.proc' ) ) { print stderr 'psf: cannot find procset for -b' ; } else { while ( ) { chop; print $OUTPUT $_; } close ( tmpfile ) ; } } if ( $m ) { # We should add Helvetica-Bold to document fonts and # add the ProcSet to DocumentSuppliedProcSets if ( ! open ( tmpfile, "$libhead/pagemess.proc" ) ) { print stderr 'psf: cannot find procset for -m' ; } else { while ( ) { chop; print $OUTPUT $_; } close ( tmpfile ) ; print $OUTPUT "/msgstring ($message) def" ; } } $_= $thisline ; #'!!EndHeaderComment'; if (!/^%%EndComments/) { print $OUTPUT $_; } next line; } if ($state <= 4 && /^%%Page:/) { if ($state <=2 ) { do eoh() ; } if ($printing) { if ($state == 3) { do phe() ; } if ($state >= 3) { do eop() ; } } $state = 3; # /* Start of Page Comments */ @Fld = split(' '); $pageno = $Fld[2]; if ( $pageno + 0 ne $pageno ) { $pageno=$Fld[3] ; } if ($rangecount > 0) { $printing = 0; for ($i = 1; $i < $rangecount; $i++) { if (($pageno >= $startp[$i]) && ($pageno <= $endp[$i])) { $printing = 1; last; } } } else { $printing = 1; } if ($printing) { if ( $twoinone ) { if ( $twofirst ) { do start_page() ; print $OUTPUT '%%Page: ' . $pagecount . ' ' . $pagecount; print $OUTPUT '%%BeginPageSetup' ; print $OUTPUT 'save ' . $p_encaps_b . '/showpage {} def' ; print $OUTPUT '90 rotate 0 ' . (- $page_length) . ' 72 mul 0.5 sqrt mul translate 0.5 sqrt dup scale' ; print $OUTPUT '%%EndPageSetup' ; print $OUTPUT '%%BeginDocument: two_in_one' ; } else { print $OUTPUT $page_width . ' 72 mul 0 translate'; print $OUTPUT '%%BeginDocument: two_in_one' ; } } else { do start_page() ; } if ( ! $twoinone && ( $reverse || $rangecount>0 ) ) { print $OUTPUT $Fld[1], $Fld[2], $pagecount ; } else { print $OUTPUT $_; } #!!Bop' . $pageno; if ( $letter ) { print $pageno . ' let_over'; } } next line; } if ($state >= 3 && $state<=4 && $printing ) { if ( /^%%PageBoundingBox:/ && !/\(atend\)/ ) { $bb_comment= $_ ; do out_bb() ; } } if ($state == 3 && !/^%%/) { if ($printing) { do phe() ; } $state = 4; # /* Page body */ } if (/^%%BeginDocument/ && ($state == 3 || $state == 4)) { $doccount++; # /* Start of included document */ if ($printing) { print $OUTPUT $_; } next line; } if ( $state<5 && /^%%Trailer/) { $trail= $_ ; if ($state <=2 ) { do eoh() ; } if ($printing) { if ($state == 3) { do phe() ; } if ($state >= 3) { do eop() ; } } if ( $twoinone && $twofirst==0 ) { print $OUTPUT $p_encaps_e. 'restore showpage' ; } if ( $pages_at_trail ) { $pages_done=0 ; } if ( $bb_at_trail ) { $bb_done=0 ; } if ( $reverse ) { $OUTPUT= 'stdout' ; for ( $i=$pagecount ; $i>=1 ; $i-- ) { if ( ! open ( tmpfile, "$tmphead$$.$i" ) ) { print stderr 'psf: cannot re-open temporary file '. "$tmphead$$.$i" ; exit 9 ; } $_= ; chop ; @Fld= split(' '); print $OUTPUT $Fld[1], $Fld[2], $pagecount-$i+1 ; while ( ) { chop; print $OUTPUT $_; } unlink "$tmphead$$.$i" ; } } #!!Trailer'; $state = 5; # /* Trailer */ print $OUTPUT $trail; $printing = 1; next line; } if ($state== 5 && $pages_at_trail ) { if ( /^%%Pages:/ ) { /%%Pages: *[^ ]* *(.*)/ && ($pageorder=$1) ; if ( $doubles ) { print $OUTPUT $_; } next line; } if ( !/^%%/ ) { do trailpages() ; next line; } } if ($state== 5 && $bb_at_trail ) { if ( /^%%BoundingBox:/ ) { $bb_comment= $_ ; if ( $doubles ) { print $OUTPUT $_; } next line; } if ( !/^%%/ ) { do trailbb() ; next line; } } if ($printing == 1) { print $OUTPUT $_; } } } $not_done='' ; if ( !$eoh_done ) { if ( $copies>1 ) { $not_done = $not_done . '-# ' ; } if ( $land ) { $not_done = $not_done . '-land ' ; } if ( $upside ) { $not_done = $not_done . '-upside ' ; } if ( $set_security ) { $not_done = $not_done . '-security ' ; } if ( $manfeed>0 ) { $not_done = $not_done . '-c ' ; } if ( $set_inputtray ) { $not_done = $not_done . '-inputtray ' ; } if ( $transparency ) { $not_done = $not_done . '-transparency ' ; } if ( $set_sort ) { $not_done = $not_done . '-sort ' ; } if ( $set_outputtray ) { $not_done = $not_done . '-outputtray ' ; } if ( $set_tumble ) { $not_done = $not_done . '-tumble ' ; } if ( $set_select ) { $not_done = $not_done . '-outputtray ' ; } if ( $courierold ) { $not_done = $not_done . '-courierold ' ; } } if ( $state<3 || $pagecount == 0 ) { if ( $orange ne "" ) { $not_done = $not_done . '-o... ' ; } if ( $reverse ) { $not_done = $not_done . '-r ' ; } if ( $twoinone ) { $not_done = $not_done . '-2 ' ; } if ( $letter ) { $not_done = $not_done . "-b$letter" ; } } if ($state<5) { if ( !$nondsc ) { print stderr "warning: Document does not conform to Structure Conventions" ; $dsc_warning=1 ; } } else { if ( $pages_at_trail ) { do trailpages() ; } if ( $bb_at_trail ) { do trailbb() ; } } if ( $not_done ne '' ) { if ( !$dsc_warning ) { if ( $nondsc ) { print stderr "warning: Document is badly structured"; } else { print stderr "warning: Document contains no pages" ; } } print stderr "warning: ignored options: $not_done" ; } tcm-2.20+TSQD.orig/bin/_cygwin_stripfile.sh0000755000175000017500000000027310077527116021411 0ustar otaviootavio00000000000000#!/bin/sh ## ## Daniel Boesswetter ## ## Fri Oct 25 11:03:05 2002 ## X=`mktemp` getfacl $1 > $X /usr/bin/strip --strip-all $1 setfacl -f - $1 < $X rm -f $X tcm-2.20+TSQD.orig/bin/mkbindist0000755000175000017500000000170410077527116017244 0ustar otaviootavio00000000000000#! /bin/sh # # script to build tar.gz distribution of TCM binaries. [ ${TCM_HOME} ] || { echo TCM_HOME is not set. Bailing out.; exit 1 } if [ $# != 2 ] then echo "Usage: `basename $0` version platform" exit fi VERSION=$1 PLATFORM=$2 TAR=gtar DISTFILE=tcm-$VERSION.bin.$PLATFORM.tar.gz PREFIX=tcm-$VERSION SRC='COPYING CHANGELOG MANIFEST INSTALL* FILEMAP README* bin/psf bin/t* doc/usersguide.html doc/usersguide/*.css doc/usersguide/*.html doc/usersguide/*.gif doc/usersguide*.ps.gz doc/wishlist/FutureDevelopments.html doc/wishlist/WishList.html lib/TCM lib/banner.ps lib/colorrgb.txt lib/help/[D-Z]* lib/tcm.conf lib/*.so man/windex man/man1/*.1' cd $TCM_HOME /bin/ls -d $SRC | sed -e "s:^:$PREFIX/:" > MANIFEST (cd ..; ln -s $TCM_HOME $PREFIX) (cd ..; $TAR -czvf $TCM_HOME/$DISTFILE `cat $TCM_HOME/MANIFEST`) (cd ..; rm $PREFIX) tcm-2.20+TSQD.orig/bin/makedepend.sh0000755000175000017500000000160610077527116017767 0ustar otaviootavio00000000000000#!/bin/sh # # makedepend_sh # copyright (c) 2000 J. Alan Eldridge # $Id: makedepend.sh,v 1.2 2002/05/29 08:27:34 henkz Exp $ # makefile= makedepend="gcc -MM" [ -f makefile ] && makefile=makefile [ -f Makefile ] && makefile=Makefile [ -f GNUMakefile ] && makefile=GNUMakefile [ ${makefile} ] || { echo cannot find a makefile ... bailing out exit 1 } marker='# DO NOT DELETE THIS LINE -- make depend depends on it.' grep "${marker}" ${makefile} >/dev/null 2>&1 [ $? -eq 0 ] && foundit=y || foundit= if [ ${foundit} ] ; then rm -f ${makefile}.or mv ${makefile} ${makefile}.or sed -e "/${marker}/q" < ${makefile}.or > ${makefile} || { echo sed command failed ... bailing out exit 1 } rm -f ${makefile}.or else echo "${marker}" >> ${makefile}; echo >> ${makefile} fi # [ ${foundit} ] ${makedepend} ${1:+"$@"} >> ${makefile} # # EOF ## tcm-2.20+TSQD.orig/bin/mksrcdist0000755000175000017500000000337010077527116017264 0ustar otaviootavio00000000000000#! /bin/sh # # script to build tar.gz distribution of the TCM sources. [ ${TCM_HOME} ] || { echo TCM_HOME is not set. Bailing out.; exit 1 } if [ $# != 1 ] then echo "Usage: `basename $0` version" exit fi VERSION=$1 TAR=gtar DISTFILE=tcm-$VERSION.src.tar.gz PREFIX=tcm-$VERSION SRC='COPYING CHANGELOG FILEMAP INSTALL* MANIFEST README* Makefile* tcm*.spec tcm*.patch tcm.lsm bin/Makefile bin/_cygwin_* bin/link* bin/mkbindist bin/mksrcdist bin/mkclasslist bin/makedepend.sh bin/makeundepend.sh bin/psf doc/Makefile doc/contributions doc/developersguide/*.css doc/developersguide/*.html doc/developersguide/*.gif doc/developersguide*pdf.gz doc/developersguide*ps.gz doc/index.html doc/sourcecode/*.html doc/sourcecode/*.gif doc/sourcecode*.ps.gz doc/specifications/[a-z]* doc/specifications/T* doc/usersguide.html doc/usersguide/*.css doc/usersguide/*.html doc/usersguide/*.gif doc/usersguide*pdf.gz doc/usersguide*ps.gz doc/wishlist/FutureDevelopments* doc/wishlist/WishList* lib/Makefile lib/help/[D-Z]* lib/banner.ps lib/TCM lib/colorrgb.txt lib/tcm.conf man/windex man/man1/*.1 src/Config* src/Makefile* src/bitmaps/*.gif src/bitmaps/*.xbm src/bitmaps/*.xpm src/??/Makefile src/??/README* src/??/*.[hcly] src/??/??/Makefile src/??/??/*.[hcly]' cd $TCM_HOME /bin/ls -d $SRC | sed -e "s:^:$PREFIX/:" > MANIFEST (cd ..; ln -s $TCM_HOME $PREFIX) (cd ..; $TAR -czvf $TCM_HOME/$DISTFILE `cat $TCM_HOME/MANIFEST`) (cd ..; rm $PREFIX) tcm-2.20+TSQD.orig/doc/0000755000175000017500000000000010077525315015324 5ustar otaviootavio00000000000000tcm-2.20+TSQD.orig/doc/developersguide/0000755000175000017500000000000010077525342020512 5ustar otaviootavio00000000000000tcm-2.20+TSQD.orig/doc/developersguide/developersguidenode7.html0000755000175000017500000002533210077525334025534 0ustar otaviootavio00000000000000 6. Output Files next up previous contents
Next: 7. Compiling and Porting Up: Toolkit for Conceptual Modeling Previous: 5. TCM Class Hierarchy

Subsections

6. Output Files

6.1 PostScript output

This is a short description of the structure of the PostScript files that is generated by the current version of TCM. This is not a lesson in programming PostScript nor a detailed explanation of each possible PostScript expression that could be generated by TCM. Instead, you are referred to the official documentation like [6,5].

6.1.1 Plain PostScript

The PostScript output files for a TCM document have the following structure.

6.1.1.1 Header

The first part of the plain PostScript output consists of the following header:
%!PS-Adobe-1.0
%%Title: <name of document>
%%Creator: <tool+version>
%%CreationDate: <current date>
%%For: <login>
%%DocumentFonts: (atend)
%%Pages: (atend)
%%BoundingBox: (atend)
%%EndComments
/ISOLatin1Encoding[
      ...
] def
EndProlog

Lines that start with %% or %! are PostScript structuring commands. The generated files conform to the PS-Adobe 1.0 file structuring conventions. (atend) means that the value is determined in the rest of the program. The ISOLatin1Encoding definition (whose body is not printed here to save space) is necessary to make sure that the entire ISO Latin-1 character set can be displayed.

6.1.1.2 Pages

Each page starts with a page setup followed by the page contents. Example page setup:

%%Page: 1 2
12.8976 9.49604 translate
0.867470 0.867470 scale
0 948.736111 translate
1 -1 scale
1.000000 1.000000 scale
0.750000 setlinewidth
%%BeginPageSetup
gsave
-0.000000 -0.000000 translate
%%EndPageSetup
The first line gives the current page label (1 in this example) and the total number of pages (2). The next translate line moves the coordinate system to the drawable paper area. Then the scale line scales X coordinates to PostScript points. The other translate and scale lines change from X to the PostScript coordinate system (in portrait mode and with scale factor 1.0). When the page would be written in LandScape and with scale factor 1.5, those three lines would be:
90 rotate
1 -1 scale
1.5 1.5 scale

The setlinewidth line sets the width of the line a bit smaller than the default, which is a bit too fat in comparison with the Xlib lines. The lines between BeginPageSetup and EndPageSetup move the page (like it is visible in the X window) that is going be written to the position of the first page (in this case the translation is zero because the example shows the first page).

After that, the lines of the current page are written in rather ordinary PostScript prose (with newpath, moveto, rlineto, closepath and stroke commands).

Strings are drawn in the following fashion: First the font is loaded when that is not already done, e.g.:

dup length dict begin
   {1 index /FID ne {def} {pop pop} ifelse} forall
   /Encoding ISOLatin1Encoding def
   currentdict
end
/Helvetica-ISOLatin1Encoding exch definefont pop
This loads the font family (in our case Helvetica ISO Latin1). Then the string is positioned and drawn, e.g:
/Helvetica-ISOLatin1Encoding findfont
10 scalefont setfont
(foobar) stringwidth
pop 2 div neg
120 add 144 moveto
gsave
1 -1 scale
(foobar) show
grestore
The above lines draw the string foobar in the just loaded font, centered at position (120,144) with point size 10. Each PostScript output page ends with:
grestore
showpage
%%PageTrailer

End finally the PostScript output ends with:

%%Trailer
%%EOF

6.1.2 Encapsulated PostScript

The first part of the EPS output consists of the following header.

%!PS-Adobe-3.0 EPSF-3.0
%%Title: <document name>
%%Creator: <tool+version>
%%CreationDate: <current date>
%%For: <login>
%%DocumentFonts: (atend)
%%Pages: 0
%%BoundingBox: llx lly urx ury
%%EndComments
/ISOLatin1Encoding[
] def
The four numbers (llx lly urx ury) are the top left and bottom right coordinates of the bounding box, i.e. the square area occupied by the drawing. After the header the font is loaded, in the same way as in plain PostScript. EPS does not have separate pages and hence does not need page setup lines. The following lines are generated to change from X coordinates to EPS coordinates:

0.867470 0.867470 scale
0 85 2 mul 117 add 0.867470 div translate
1 -1 scale
%%EndProlog

0.867470 is the (fixed) factor of X coordinates/PS coordinates. As a remark, I forgot the exact meaning of the second line, but is works in any case. After that the entire drawing is written as PostScript, the same way as it is done with plain PostScript (but without page setups). The output ends with the same two lines as plain PostScript.

6.1.3 PSGrafport

All PostScript generation is hidden in the PSGrafport class. It contains the functions that write headers and page setup lines to the PostScript output file and for each Grafport function it contains a counterpart that writes a piece of PostScript. For example Grafport has a virtual function DrawRectangle(int x, int y, int width, int height) that draws a rectangle to the Grafport. XGrafport implements this function as:

 
XDrawRectangle(display, window, xorGC, x, y, wd, ht);
I.e. it draws a rectangle on an X window. Whereas PSGrafport implements this function with:
 
fprintf(fd, "newpath\n");
fprintf(fd, "%d %d moveto\n", x, y);
fprintf(fd, "%d 0  rlineto\n", wd);
fprintf(fd, "0 %d  rlineto\n", ht);
fprintf(fd, "-%d 0 rlineto\n", wd);
fprintf(fd, "closepath\n");
fprintf(fd, "stroke\n");
I.e. it writes a PostScript fragment to the file that would result into the printing of a rectangle.

To add another output format to TCM, you probably need only to make another specialization of Grafport and implement each Grafport function in that class to write a piece of output in that format. For instance, for writing the Fig output (Produced by Xfig) we implemented a FigGrafport that writes for every Draw-functions a part of Fig-format to file.

6.2 TCM file format

The TCM file format of the current version is described in full detail in appendix B of the User's guide.


next up previous contents
Next: 7. Compiling and Porting Up: Toolkit for Conceptual Modeling Previous: 5. TCM Class Hierarchy
Henk van de Zandschulp
2003-01-07
tcm-2.20+TSQD.orig/doc/developersguide/previous_motif.gif0000755000175000017500000000033410077525334024257 0ustar otaviootavio00000000000000GIF89a?ooo[!,?I޼j~㕶.Lq6z Hir"?$`)|J{Č\vSUM߬95[0Er5WxEWeCxhyfFfY)'#؈:+H4{[3 , 5. TCM Class Hierarchy next up previous contents
Next: 6. Output Files Up: Toolkit for Conceptual Modeling Previous: 4. TCM User Interface

   
5. TCM Class Hierarchy

A representation of the C++ class hierarchy can be automatically generated with doc++. doc++ is a documentation system for C++ programs capable of generating output for HTML and LATEX. doc++ follows the approach of maintaining one source code that contains both the C++ program itself along with the documentation in order to avoid incompatibilities between the program and its documentation. doc++ documentation is solely hidden in standard C++ comments (the text that appears in the doc++ files is C++ comment that starts with //, instead of the standard C++ convention to start comment with ///). doc++ is free software, subject to the GNU PUBLIC LICENSE. It is included in the TCM documentation source distribution and it can be found in the doc/docsrc/docxx subdirectory or it can be downloaded from http://www.zib.de/Visual/software/doc++/index.html.

A doc++ LATEX document of the entire TCM source tree can be made automatically and from that HTML and PostScript documents can be generated. These documents can be found in
doc/sourcecode/index.html and doc/sourcecode-2.0.ps.gz.

The classes in the LATEX document generated by doc++ are alphabetically ordered. Each class has a section which consists of a picture of its base class and its derived classes, a list of its public and protected members plus relevant comment. As the files reside in different directories and are used in different libraries or executables, its `scope' is mentioned at the end of the listing of a class. At the end of the doc++ documentation you can find the entire class specialization graph. In the HTML documentation generated by doc++, a distinct HTML page is generated per C++ class. Connections between classes (variables, function arguments, base/derived classes) are automatically translated to HTML-links and there is an index file which contains links to all classes in alphabetic order.


next up previous contents
Next: 6. Output Files Up: Toolkit for Conceptual Modeling Previous: 4. TCM User Interface
Henk van de Zandschulp
2003-01-07
tcm-2.20+TSQD.orig/doc/developersguide/next_motif_gr.gif0000755000175000017500000000025410077525334024052 0ustar otaviootavio00000000000000GIF89a%ooo!,%}ڋ2bUbK +7nj:f#a)gy5Nq+d]͈^fbjۜXL$XBXr8c)9IYi`Y;tcm-2.20+TSQD.orig/doc/developersguide/developersguidenode9.html0000755000175000017500000000544610077525334025542 0ustar otaviootavio00000000000000 8. Wish List and Future Plans next up previous contents
Next: Bibliography Up: Toolkit for Conceptual Modeling Previous: 7. Compiling and Porting

8. Wish List and Future Plans

There are some additional texts in the doc/wishlist directory. The file WishList.html contains a list of wishes for the current set of editors. At this moment it contains over 200 items in categories and they are given priorities. Chances are big that your wishes are already mentioned there. If not, let us know. Adding an item to this list won't cost us a lot of time :).

Furthermore, there are lots of plans for further developments, which are listed in a file called doc/wishlist/FutureDevelopments.html. Our vision is to make from TCM a full featured toolkit, both for Structured Analysis and UML.



Henk van de Zandschulp
2003-01-07
tcm-2.20+TSQD.orig/doc/developersguide/developersguidenode8.html0000755000175000017500000004307410077525341025536 0ustar otaviootavio00000000000000 7. Compiling and Porting TCM next up previous contents
Next: 8. Wish List and Up: Toolkit for Conceptual Modeling Previous: 6. Output Files

Subsections

   
7. Compiling and Porting TCM

Before you start compiling or porting TCM you first have to unzip and untar the source code distribution in the same manner as the executable distribution. See then the file $TCM_HOME/INSTALL which contains the most up-to-date installation instructions. See chapter 3 for what files are included. Make sure that before compilation the TCM_HOME environment variable is set to the directory where the distribution resides (the ``root'' directory of the entire distribution, not the src directory!).

The TCM directory tree contains a set of Makefiles and configuration files. The Makefile in the src directory should be a symbolic link to Makefile.compiler. Config.tmpl should be a link to Config.tmpl_platform. src/Makefile contains the targets specific for some compiler (g++, Sun CC, etc.) and Config.tmpl contains settings for the system. For each operating system to which TCM has been ported (Linux, Solaris, HP-UX, etc.) a distinct Config.tmpl file is supplied. The default make targets are in src/Makefile.GEN and the default settings of the various Config.tmpl files are in src/Config.GEN.

7.1 Compiling TCM

The most simple way to compile and install TCM is to type make for the Makefile in $TCM_HOME. This default target will set the right links for the src/Makefile and src/Config.tmpl and then it will write to standard output what are the following targets that you can build. Of course it wise to check the setting of src/Config.tmpl yourself first before you continue. The next possible targets are:

  • make depend, for making file dependencies.
  • make execs, for making the object libraries and binaries and then move them in the lib and bin directories respectively.
  • make install, for copying the binaries and all the other files of a binary distribution to the directory where you would like to install TCM. /opt/tcm is the default directory but that can be changed in the Makefile by setting TCM_INSTALL_DIR.
  • make all, which is the same as make depend execs install.
  • make docs, which tries to (re)generate all documentation in HTML, PostScript and PDF format in the doc subdirectory. This works only of course if you have installed the document sources in docsrc.
  • make clean, which removes all binaries, object and temporary files.

Instead of make install you can also call the scripts mkbindist or mksrcdist to build a tar.gz file with the binaries and the source code respectively. They were treated in chapter 3.2.

For compiling TCM you can also go directly into the src directory. There you are able to build individual editors and individual libraries. As usual, compilation is controlled by a set of Makefiles. In the src directory there are a number of configuration files and Makefiles.

7.1.1 Compilation configuration files

The configuration files in the src directory are called Config.tmpl_suffix, one for each of the different platforms (platform as file name suffix). There is a file called Config.GEN which contains reasonable default values and is included in the Config.tmpl files. The configuration file defines which compiler is used, the compiler flags, the location of the Unix and X include files, the needed Unix and X libraries and their locations. Ideally, this is the only file you need to tailor for compiling TCM on a Unix system. To compile TCM you also need lex and yacc (or the GNU variants flex and bison). The files that are generated have to be compiled by an ordinary C compiler. Therefore, define in Config.tmpl, LEX, YACC and Cc. Before compiling TCM, make a symbolic link called Config.tmpl to the configuration file of the desired platform. The declarations in the Config.tmpl will be included in the Makefiles.

Configuration options consist of Variable name = Value. To append a value to a variable name you can use += instead of =. A value can contain the contents of a variable that was defined before, by using the notation $(variable name). The following configuration options can be set:

  • CC. This is the C++ compiler. This is /usr/bin/g++ by default.
  • Cc. This is the C compiler. This is /usr/bin/gcc by default.
  • CFLAGS. These are the flags given to the C++ compiler. By default these are -Wall -pedantic. You can add compiler-specific options for C++ templates, optimizing options or add the option -g to add debugging information.
  • INCLUDEDIRS, the system include directories (-I flags) for the compiler.
  • LD_FLAGS, the library flags (-L and -R flags) for linking.
  • LD_LIBS, the libraries against which TCM is linked.
  • LEX, the (f)lex lexical analyzer.
  • MKDEPEND, the command that is called for make depend.
  • MKDEPENDFLAGS, the flags for make depend.
  • MOTIF_HOME, the directory where Motif or LessTif is installed.
  • STRIP, the Unix command to strip binaries. When you don't want to strip (because debugging information would be lost), set it to /bin/echo.
  • SHAREDFLAG, special compiler flag, such as -shared or -G, to generate shared object libraries.
  • SYSFLAGS, a number of TCM-specific flags for the compiler:
    • -DLINUX, -DSOLARIS, -DIRIX, etc. Set this to the target operating system.
    • -DLESSTIF. Set this if you compile with LessTif, don't set it if you use Motif.
    • -DDEBUG, -DDUMPWINDOWTREE, output some debugging information.
  • XWIN_HOME, the directory where X windows is installed.
  • YACC, the yacc, compiler compiler.

7.1.2 Makefiles

The main Makefile contains the rules for how to build the libraries and the executables in the subdirectories. Per type of compiler there is a distinct Makefile. They are called Makefile.suffix. The default make targets are in the file Makefile.GEN and it's included in the other Makefiles. Before compiling TCM, make a symbolic link called Makefile to the Makefile of the desired compiler. Each src-subdirectory has its own Makefile which is platform- and compiler-independent. If everything goes normal they need not be changed when TCM is recompiled or ported.

The Makefile in the src directory has the following top-level targets:

  • make or make all. Compiles the entire distribution (default compilation).
  • make allx. Force compilation into a few executables (i.e. all diagram editors and all table editors are each compiled into a single executable). This is the default for g++. You can create the needed symbolic links for the different editors with the script $TCM_HOME/bin/linkx
  • make ally. Force compilation into some more executables than allx. Related tools such as all data view editors are compiled into one executable. The individual tools have to be soft links, that can be made with the script $TCM_HOME/bin/linky
  • make allz. Force compilation in which each editor is compiled in a separate executable. This is the default for the Solaris CC compiler.
  • make libs. Compiles all object libraries. These libraries can be static or dynamic, depending on the compiler that is used.
  • make staticlibs: make all static object libraries (the libXXX.a versions).
  • make dynamiclibs: make all dynamic object libraries (the libXXX.so versions).
  • make clean. All object files in the source directories are removed.
  • make depend. Create dependencies in the Makefiles. You are advised to do a make depend for a make all when you compile TCM for the first time.
  • make library. Compile given library.
  • make tool. Compile given tool (only tool specific part, not the libraries that it needs). So you have to type in make dynamiclibs tgd when you want to make TGD and the dynamic libraries that it needs.

When a library is compiled, it will be moved to $TCM_HOME/lib and when an executable is compiled it will be moved to $TCM_HOME/bin. This means it will overwrite the old version.

Which default compilation is performed, depends on the kind of compiler that is used. The Sun CC compiler, whose Makefile is Makefile.suncc, has make dynamiclibs allz as default and the GNU g++, whose Makefile is Makefile.gcc, has make staticlibs allx as default.

7.2 Porting TCM

In principle, TCM can be ported to any Unix system that has X Windows, Motif and a C++ compiler that can handle templates. The easiest way is to copy and adapt an existing Makefile and Configuration file and then try to do a make clean, a make depend and then a make all.

Most of the source code is platform independent. Only at a few places there are some Unix specific parts which are compiled conditionally. This is indicated in the source code by for instance '#ifdef LINUX'. The Makefile compiles its targets with the -D flag (see the Config.tmpl file) for instance -DLINUX. The files that probably need some modification, because they use conditional compilation are: gl/system.c, gl/link.c, gl/util.h and ed/document.c. The best thing to do before you port is to do some greps on the sources to see what sources should maybe be changed when ported. For instance: grep SOLARIS ??/*[hc] ??/??/*[hc] ; grep LINUX ??/*[hc] ??/??/*[hc] (do this in $TCM_HOME/src), will show what part of the sources have things specific for Solaris and Linux.

Likewise, a few lines of code could be different for Motif and LessTif. When TCM is compiled with LessTif then the compiler should be supplied with the -DLESSTIF flag. In the source code you will find some #ifdef LESSTIFs.

7.3 G++ specific problems

The GNU C++ compiler g++ is somewhat limited in handling template classes. GNU g++ does not implement a separate pass to instantiate template functions and classes at this point; for this reason, it will not work, for the most part, to declare your template functions in one file and define them in another. The compiler will need to see the entire definition of the function, and will generate a static copy of the function in each file in which it is used. G++ does not automatically instantiate templates defined in other files. Because of this, code written for cfront will often produce undefined symbol errors when compiled with g++. You need to tell g++ the file where they are defined.

The solution for TCM was, when __GNUC__ is defined, to include in gl/llist.c the template declarations that you need from the file gl/instances.h. u Because different groups of editors need different declarations, several files with instances are created in different source code directories and during compilation the needed file is copied to gl/instances.h and gl/llist.c is compiled and libglobal.a is generated again. The instance files contain not much more than declarations of template instances. This process is controlled by the Makefiles. This solution only works with static linking of libglobal (because different libglobal libraries are needed by the executables). In principle the other libraries can be linked dynamically by g++ This can be achieved by issuing the target: make semistaticlibs.

By the way, the List class is in the file gl/llist.[hc] because the file name list.[hc] caused some strange name clashes while using Sun CC compilers.

When you want to compile TCM with g++ on another system (use version 2.7.2 or higher), then take Makefile.gcc as a basis for your Makefile and take a look in Config.tmpl_linux because on Linux the g++ compiler is used by default.


next up previous contents
Next: 8. Wish List and Up: Toolkit for Conceptual Modeling Previous: 6. Output Files
Henk van de Zandschulp
2003-01-07
tcm-2.20+TSQD.orig/doc/developersguide/developersguideimg10.gif0000755000175000017500000002163710077525341025240 0ustar otaviootavio00000000000000GIF89a;`xxxlll```TTTHHH<<<000$$$ !,;`@ $@ihlp,tmx|pƤrl:ШtJZجvzxL.GHkn|Nu񀁂]SgONRD?[Ly}Tb${{~KW|g ' &&"& ܴwޓPfMɬKo .W0cFd[ `K&@ $h0iL:d ]:ly=Dᠤ% `P ڔ))` %Gp#b:#Ou찘lF% `Wjߎ ʒM`H: gW[~2na)GܶZz*GzkS yl$riV4!A@8`qhݫWZB4" 4ͱR,&KY:ŵԔnܚ;mgZ("%^zI+KZy!U :p :qg fõ,Y#2+,3r3pοUқkx\A#d@=4l*m#<5N!up7̷ImGZ44!i]Nl`qeW'ߏW4P4@Sqjz:`snݝ39 o]5 Щ6 Q90it~an.=*"MO݃~ֿ}{,"~}kӯoo8羷 +)d `o= Zv.y ?ApN Qx-|&k@71px-!a @8tC[^gD$:1""q*Z$\ cδ(2f$^C 90C## yŽȻD:=|_ III:L^*IgęC5JJ^ldS[,)b'I,0 XJo-!x):{Q+*fC/k a5S*ZenDS\,`Xri[ѲƷ L{h8TЗHE)ϋ;t3T'.IM @9х MCUL^t6Y2 q4C=aielrK҂rMI ~*D#eoSC11~3.LPGq:d=rW'H3Y*=1F`Nՠr_*/WgM_ q!F>`r,~#+VKZTYgK{F'WelGktRj{btX @:W`ZHy+:~Tb*=jyR.jʰ *׀ UK7lMxq6I/Fk7 ޥV \roEp{ZN #7Òlma͋U-nGڢ&$qa*6vMmQz(뷮Mjuq96Ot-bX ')YklCd|;I~ap6`YW_֥=XAFy#<{x͔ g-x{SGR}.I/Ѱ}3,F;Cį3'LGT8] N;utN`=Y\op@+U{i"zi1̜^'z‘֝KGbסŴٱPa& wx"NGBM0k 3 |nf\Ud@Ա}=fmToKV;po4a jv~Nx},ۍA.bGҍv;a/-ȟ;K|?ssutݙ.̳&*)w:IItY+|ǣ^ ߪERu֧.$pb8v7=k?iϞ}]Sf˱}I7YiK3OY_6CNY>x[O>{=M{"zhdx:,\s[7}C;>/|-r?Cwfwt'\F|3S x~Li7`#MD8`M(1F7)7xw,U &&$aWnum٦G-Χ>EYT:IVvv;U4n5@uX\.;ɳx!J[5?J:s;6E{ tgf0q{p̪ۣۛ[w";kj~ ָ4:p kklKos˻ koz'+ɻ{dcʀ$KHkid[[ېkr r| l[ lA[4\E|N|D G ,ؽ&oh+u/lEW3 \Z .|߫T+i= .j{C|DAk5 %(XHRK-O׃BLD;%mUCH a, PdT-m,zr({L}_]ƅ ȇ(llo%05lÓܰ,Ex,[<ʹŦ3ʹYm9N”Z w͈Lڏu.ୋz܀>iņHӄH_y眾q^דtkӰۻ6FP"[~ Mɠ ~f3ݹw߽͟Ze*JZ{^ʞҷ.`>(ci'-2-3nZ^nN .6 5?5K>a!> O]-;%$o;p^"e.gnD]b.oQKN}=!4]_? NdN甆'8/񊾉@h:BHm|#^9E!]^x3އQ1n߀oN{S8|MHo8kɑ(QgMi?R ΏQm?؈y3~ojo9o=2֟S?jOi{0s #YB뚱L;?0(#2\2gʨ. r/ cNDhqG2 ̠_"c#@dDBa#ji'*!bk,mm  C]H/ 0Amtͪ+4 l6w/gdqLyn$75vk>.>,/֓~u+!ĈPE7rAm0N[$ʔ*Ɍ2WҬifYt)'РB9dC2mhIH(uj*[PJJgְbfɲm6g,/{.޼QHY]++ؽu 3nSul2MNL355bѪWO$mȴϝYӮ 51ةcG7‡/܈ʗ/9tȣSІ6kGY-w[0+ϺiwçD?[tH_o > :`|ٷA v#aL hMjxX*xߌ4.qy(ۊ(dDbkh#ooц%AC@KX–0tei`W5$n©N9^ qv"xfވdnJ"ƀ&9]ZHE/-, c#2 `4H%1ǺDr،%EGu"N*ق,(KX0,PK/Җ./[@̑9.F~P"6^&3oSFhBS[ χpYcI R,QX&BiE3niGCbRj;bǤkyA=jhFMNRmI>jQYiխ&5 %Mձ/t.%Oҵn}+\*׹ҵ|^U-M+a˽'U,dwX>6ue{zrvEf;+ZN֫=-m>XVVv}-lckDjiKUݶ5#o\Tk5urcִMU._۹5WnF݁p}Dwgr{^as/p_wz ^\7][+Z7D`V׸, `N~ 1_m8FoCxVfQg$ﵞ0_X XSbwxJ&'yPxM^&s[&_7 55a(/40 fXc.q9kl1hԬg#X.4ל-4! ?Ow.`Gp\"N]lp%Ǫڶz PTI1Df]ٝ!U!bjA,秐 ؕ FpDƯs[sSDMG18ԍ0P֜>ty4/ӌ\p jg'A#7z7E_mխfz\s,AAR/O%=;G,z ,xV 2SQ6\l>ݗŏà܏7pgjO~Ǘ[?9y^=WW2!`_-!\Ÿ琟`l]e` Ni  b] 6u!z_!ٓ_"!6e=J^~!_nabu!am "Z!g!a!aa!b a}!Y})"޽ &f&n"'v'fTqEfbݡ"ʠбb*b"+b-(XNډb,=)#S@cDe2c1f3&c43ڐ64Xطeck,Nא Dc5Ϭ"r% L#m5[[.@:_ڔ< d^<-&/b,@)M0FE6x%@XJ3$)@2b @/8)Ѓ=H?r5ҤJc(eBP9:QZbRZA2S*eTRcSvcUQm%AA:bem]e%eZE.Pb$:@ҥG|"\<^\e`V]4ba`^bb]ޟdN&eVe^&LW6m&g2g~:hbi&&j*j&klƦh=&MIC^&A&@yǯAQg ɋ˸AX2Ц ᛾?'wVbz"tg*Φ{BV{g-'}|g b~.g$ހ}(RYf(&.(j ;tcm-2.20+TSQD.orig/doc/developersguide/developersguideimg1.gif0000755000175000017500000000452310077525341025153 0ustar otaviootavio00000000000000GIF87a]{{{yyyuuusssqqqoookkkaaa[[[YYYWWWSSSOOOKKKIIIEEECCCAAA777333111---+++)))'''%%%!!! tttrrrfffddd^^^\\\XXXVVVRRRNNNLLLJJJHHHFFFDDD@@@>>><<<:::888666222000,,,***(((  ,]@ H*\ȰÇ#J8A$2F@Ǐ 8tQH$e\ɲ˖A IC/s=6 TsG\3&S[E#$HGš A./X6*]sK#(,2P<-QbȦM_ T$"Dt0!NAclbuj=Zt(I+g88)R)/h@@Zƫ_0?2pdDZb`$ppR$׭EzwD`%qP`>[c`U O'EL016R ),_lARN5樣tuWFĄG/PdpЛSTAXT$ D .ASQ%U2 9MPr.Phf:П Rd$Ոg}$aJFu( 1*ꨤ -mi1 --EZ-A$] **ف 5ԠE:q"ܠlP*RL,,yz9Win(%kN8@TGw$*I PnG;u6](0Rz>TBx&4@dBc^z)o ĕy(O%"=A\8ovk;tcm-2.20+TSQD.orig/doc/developersguide/developersguideimg11.gif0000755000175000017500000000013310077525341025225 0ustar otaviootavio00000000000000GIF89a TTTHHH !, @ X*F5@DC f(q%Z$;tcm-2.20+TSQD.orig/doc/developersguide/up_motif_gr.gif0000755000175000017500000000022110077525341023510 0ustar otaviootavio00000000000000GIF89aooo!,b˭bZ `؅ҷ!9 zj*Kќ >X6 Lvbmbl2'^}WLv兽 QPY%krM/P;tcm-2.20+TSQD.orig/doc/developersguide/developersguidenode3.html0000755000175000017500000001673510077525341025535 0ustar otaviootavio00000000000000 2. System Architecture next up previous contents
Next: 3. Source Code Organization Up: Toolkit for Conceptual Modeling Previous: 1. Introduction

2. System Architecture

In this chapter a high level overview of the TCM software system is presented. In figure 2.1 TCM is logically decomposed into a number of subsystems. Each subsystem is then worked out further as an UML static structure diagram (SSD) in subsequent figures. All classes in these SSDs also exist in the source code, but not every source code class is mentioned in these SSDs. The classes that are not mentioned are either implementation classes (data structures, user interface widgets etc.) or they are specializations of the classes that are mentioned for specific editors. The same applies to the relationships between the classes. Note also that we do not show the attributes and operations of the classes because that would clutter up the diagrams too much. But a complete and accurate overview of all classes of the source code and their attributes, operations and specialization relationships has been generated automatically and is described in chapter 5.

This system architecture is rather conceptual, it does not say exactly how the source code is organized physically. In chapter 3 the physical source code structure is presented.


  
Figure 2.1: Subsystems.
\includegraphics[angle=90,height=6in]{p/FSubsystems.eps}


  
Figure 2.2: Editor subject areas.
\includegraphics[angle=90,height=7.5in]{p/FEditorsSA.eps}


  
Figure 2.3: Shapes and Graph subject areas.
\includegraphics[angle=90,height=7.5in]{p/FShapeSA.eps}


  
Figure 2.4: Table subject area.
\includegraphics[angle=90,width=\textwidth]{p/FTableSA.eps}


  
Figure 2.5: Viewer subject area.
\includegraphics[angle=90,height=7.5in]{p/FViewerSA.eps}


  
Figure 2.6: Printer subject area.
\includegraphics[angle=90,height=4in]{p/FPrinterSA.eps}


  
Figure 2.7: Window subject area.
\includegraphics[angle=90,height=7.5in]{p/FWindowSA.eps}


next up previous contents
Next: 3. Source Code Organization Up: Toolkit for Conceptual Modeling Previous: 1. Introduction
Henk van de Zandschulp
2003-01-07
tcm-2.20+TSQD.orig/doc/developersguide/contents_motif.gif0000755000175000017500000000034110077525341024234 0ustar otaviootavio00000000000000GIF89aAooo[!,AM޼r扆㕶Lg6Cwv/1b(fS\tƝnfS)VH6vMwnt-OEq'zWEǒ5HHG'ƘW)DGi  +[Ak[3" Toolkit for Conceptual Modeling (TCM) Design and Implementation for version 2.01 next up previous contents
Next: Contents

\includegraphics{p/Teapot2a.ps}
Toolkit for Conceptual Modeling (TCM)
Design and Implementation
for version 2.01

Frank DehneHenk R. van de Zandschulp
Division of Mathematics and Computer Science Department of Computer Science
Faculty of Sciences, Vrije Universiteit University of Twente
De Boelelaan 1081a, 1081 HV Amsterdam P.O. Box 217, 7500 AE Enschede
The Netherlands The Netherlands
frank@cs.vu.nl henkz@cs.utwente.nl

February 12, 2001



 

Henk van de Zandschulp
2003-01-07
tcm-2.20+TSQD.orig/doc/developersguide/developersguidenode2.html0000755000175000017500000001364110077525341025525 0ustar otaviootavio00000000000000 1. Introduction next up previous contents
Next: 2. System Architecture Up: Toolkit for Conceptual Modeling Previous: Contents

1. Introduction

This report describes the design and implementation of the Toolkit for Conceptual Modeling. This is a working document, supplied together with the source code. It is not intended for separate publication.

TCM consists of a number of X/Motif-based diagram and table drawing tools. This document tries to give insight into how TCM is accomplished from the designer/programmer's point of view. The user guide and reference manual [2] describes what TCM does from the user's point of view.

TCM is implemented in C++ [13] and it uses the standard X Windows libraries Xlib [3] and Xt (X toolkit intrinsics) [7] and it uses the OSF/Motif widget set [12]. TCM can be used under any X11 window manager. TCM has been ported by us to SunOS 4.1.x, Sun Solaris 2.x, Linux 2.x, IRIX 6.x, AIX 4.x, HP-UX 10.x and OSF/1, But TCM is portable to any Unix system that has a C++ compiler and has the development libraries for X Windows and Motif (or LessTif, the free Motif clone). TCM uses the Motif widget library together with the Xlib and Xt libraries for its graphical user interface. These libraries have a C API. Books on Motif programming which have had influence on TCM are [1,4,15,14]. Books on Xlib and Xt programming which are used while writing TCM are [8,9,10,11].

This document is a stepping stone for a designer/programmer who has access to the TCM source code. It expects that you have knowledge about C++, X/Motif and Unix. This document tries to offer:

  • An aid for compiling and porting TCM.
  • An overview of the system architecture and the source code organization. This should make it easier to understand the software and to make it easier to write additions and modifications.

This document is kept rather short intentionally, because it is not possible to anticipate on every possible question or problem. Furthermore, TCM is rapidly evolving so that many things would be quickly outdated and each new release would be slowed down by a documentation update. When you have any questions or comments about this document you are advised to e-mail them to tcm@cs.utwente.nl


next up previous contents
Next: 2. System Architecture Up: Toolkit for Conceptual Modeling Previous: Contents
Henk van de Zandschulp
2003-01-07
tcm-2.20+TSQD.orig/doc/developersguide/next_motif.gif0000755000175000017500000000025410077525341023360 0ustar otaviootavio00000000000000GIF89a%ooo[!,%}ڋ2bUbK +7nj:f#a)gy5Nq+d]͈^fbjۜXL$XBXr8c)9IYi`Y;tcm-2.20+TSQD.orig/doc/developersguide/developersguidenode5.html0000755000175000017500000005664110077525341025537 0ustar otaviootavio00000000000000 4. TCM User Interface next up previous contents
Next: 5. TCM Class Hierarchy Up: Toolkit for Conceptual Modeling Previous: 3. Source Code Organization

Subsections

4. TCM User Interface

4.1 X/Motif user interface


  
Figure 4.1: typical X/Motif application structure.
\includegraphics[width=4in]{p/gui.eps}

Figure 4.1 shows the relationships between the built-in X, Motif and Unix libraries and an arbitrary X/Motif application. All X, Motif and Unix libraries have a C interface (functions, defines, typedefs, structs, enums, unions and variables). When a library is depicted on top of another library, this means that a library is implemented by means of the interface provided by the underlying layer. You are referred to the X and Motif books and manuals in the list of references at the end of this text.

The TCM X/Motif user interface is restricted to that part of the source (classes and functions) that directly uses the Motif, Xt and Xlib libraries. That part consists of most of the classes in the src/ui directory and some of the classes in the other editor libraries. The names of the editor specific user interface classes all end on Window or Stubs, such as ERWindow, DFWindow and DiagramStubs, TableStubs etc. The window classes are all specializations of the abstract class ui/MainWindow. The stub classes contain functions that are called from the user interface widgets (menus, push buttons, text fields etc.) and these functions in turn call application specific functions of non-GUI objects.

The ed/DrawingArea class is not part of libgui but of libeditor because it also has application specific behavior (albeit at a high level). The drawing area needs a viewer class (a descendent of class ed/Viewer). The viewer class should provide functions that are called when mouse buttons are pressed or dragged in the drawing area, when the mouse pointer is moved or when a characters are typed in while the mouse pointer is in the drawing area.

When asked what code contains X/Motif calls (and forms the GUI) then the answer is: almost all code of src/ui, all classes that end on Window or end on Stubs and the DrawingArea class.

The entire TCM distribution of the current version consists of about 450 classes and about 83000 lines of code (source and headers files, including white spaces and comments, but excluding the 20-line header part of the GNU General Public License). The X/Motif dependent part is about 19000 lines of code. This is the part that should be rewritten when TCM is translated to a non-X Windows environment.

The TCM user interface is more or less insulated into a restricted part of the source code, put in a number of C++ classes that are clearly distinguishable from the rest. But the user interface code is spread over all the TCM libraries (except libglobal). The reason for this organization is that factoring out the commonalities between all different tools was for us more important than a complete separation of the entire application code on one hand and the entire user interface code on the other. This means that each diagram editor has its own specific node and edge buttons. The code for creating tiled buttons in general is part of libgui but the specific initialization is done in the code of a specific diagram editor.

The approach of factoring out commonalities was a design for evolution and that has proved to work for TCM. It makes it relatively easy to add new tools or modify individual existing tools while maintaining a stable core of libraries and unrelated tools. When features are added to some library or to some tool, all tools that are included in the area of that library or tool (see figure 3.1) are also updated minimizing the risk of code redundancy or inconsistencies.

4.2 User interface implementation

4.2.1 Overview

Like all X11 applications, the TCM tools are event driven. This means they have the following basic structure:

1.
Create the widgets.
2.
Register the event handlers for these widgets.
3.
Go into the main event loop.
4.
Activate the appropriate event handler when a specific event occurs on a specific widget.
5.
Return to the main event loop when done.

When a TCM tool is started the widgets that form the main window are created. The class ed/EditWindow and its specializations contain the functions to create the constituent parts of the main window. These widgets have one or more so-called call-back functions: the widget reacts to a certain set of X events (that set is built-in) and when such an event occurs a user-supplied action, in the form of ordinary C functions, will be called. In our implementation we do not use ordinary C functions but instead we provide C++ static member functions.

An exception to this use of callbacks, is the drawing area widget which, by default, does not react on the events that are needed to draw pictures as we like to do in TCM. Therefore, so-called translations are used, an X-Toolkit data structure to define some specified mapping of X events to user supplied actions. All details of translations and drawing area events are hidden in the ed/DrawingArea class.

Most pop-up window dialog widgets are created during initialization. When they are popped up they do not have to be created (which is much faster) and when these dialogs are dismissed they are not destroyed, but they are simply kept unmanaged (invisible). An exception to this are so-called message dialogs, for error and warning messages etc. These are created on the fly because we can not determine in advance how many of which kind will be necessary.

A special kind of message dialog is the question dialog which is application modal. This means that the user can only respond to this dialog and other user actions in the applications are prohibited. This is necessary when the application has to have an answer before it can proceed (e.g. the `save before quit?' dialog).

The main event loop is built-in in Motif, as well as the calling of the event handlers (via callback or translation).

4.2.2 Application startup

In contrast with an ordinary C program the editors don't start by directly entering the main() function. Instead, each editor is compiled with a distinct file ??editor.c, e.g. gdeditor.c for TGD. In that file two global objects are created (but the two instance variables are not visible outside this file). For example:

 
Application *app = new Application("Tcm");
MainWindow *mw = new GDWindow("Tcm");
This means that the very first thing that is done on start-up is calling the constructor
Application::Application and then the constructor GDWindow::GDWindow. So, for each editor first an instance of class ui/Application is created and then an instance of an editor specific main window class is created (but both are not initialized yet). MainWindow and Application are both part of libgui. Specific main window classes such as GDWindow are specializations of MainWindow and are included in the specific diagram editor sources.

There should be just one instance of class Application per editor instance, which can be accessed via the global variable named theApplication. The application opens the X display, sets the color map and does some other things that are applicable for the entire application. Furthermore, the application class keeps track of a list of the application (main) windows. The current TCM implementation is limited to a single main window (the other windows are made as pop-up dialog windows) but in principle the framework of libgui can be utilized in programs that have multiple main windows.

After the creation of both class instances, the function main(argc, argv) is entered in which theApplication->Initialize(argc, argv) is called. The main function is generic and is part of libgui. The application then creates an object config of type Config, which reads in the configuration file and keeps tracks of various editor defaults. Then the application initializes the Xt application context and subsequently calls the main window initialization functions.

The main window initialization consists of the creation of the main window widgets. After the main window widgets are created, some other important objects are created (in the DiagramWindow or TableWindow class), notably:

  • printer of class ed/Printer. This object keeps track of all page and print options and takes care of printing and generating PostScript.
  • helper of class ed/Helper. This object shows the on-line help messages. It reads the help messages from file.
  • document of an editor specific specialization of the abstract class ed/Document, depending on the base class of the main window. E.g. GDWindow creates GDDiagram, DFWindow creates DFDiagram etc. The document object keeps track of the document information (like document name, author etc.) and takes amongst others care of loading documents from file and saving them to file.
  • Depending on the kind of document that is created some extra objects are created such as a graph object for diagram editors (a GDGraph in the case of TGD), that manages the nodes and edges of the document and a viewer object (GDViewer in the case of TGD) that manages in the case of a diagram editor one or more views containing a set of graphical shapes. In the case of a table editor the viewer object manages the rows and columns of the table.

These objects (of which exactly one instance exist per main window), will be supplied as parameter to the Motif callback functions 4.1. The callback function are static member functions of one of the stub classes. When the stub is called then the object is casted to the right type (because the parameters to stubs are simply pointers) and the appropriate class member of this object is called possibly with some other parameters that are supplied to the stub.

And finally, after the creation of the main window, the application object and the other main editor objects, the X main event loop is entered, giving X the control.

4.2.3 Main window structure


  
Figure 4.2: Main window of the generic diagram editor.
\includegraphics[width=6in]{p/mainwin.eps}

See figure 4.2 for the basic main window's widget structure. The boxes are Motif widgets (widget type and name between parentheses). The arrows connect widgets with their parents. The root is the top-level shell (TCM). To be more exact: the figure shows the main window of the generic diagram editor, TGD. The other diagram editors look almost the same, the main difference are their node and edge buttons. The table editors are almost similar too but they do not have node and edge buttons of course.

When libeditor.so is compiled with the option -DDUMPWIDGETTREE, a textual representation of the widget structure will be written to standard output when the editor is started (its output is also used for making this figure).

The details about creation of the widgets can be found in the classes ui/MainWindow, ed/EditWindow, ed/DrawWindow, dg/DiagramWindow, tb/TableWindow etc. See the class hierarchy of chapter 5 for the relationships and all the members of these classes.

4.2.4 Calling functions from the user interface

Menus are created by the constructor function of class ui/Menu. For an example for how to create a menu see dg/DiagramWindow::CreateMenuBar.

The items of a menu are specified by means of the ui/MenuItem class. A menu contains a list of menu items, which can be supplied to the menu constructor function. The menus common to all drawing editors are made in ed/DrawWindow, the menus common to all diagram editors are made in dg/DiagramWindow and the menus common to all table editors are made in tb/TableWindow. Likewise, menus that are specific for a single editor, are made in the corresponding main window class.

One of the fields of a MenuItem is the function that will be called when the menu item is selected. These functions are called stubs and have to be static C++ class members. The functions that are supplied are all part of a ...Stubs class which consist entirely of these static functions. Menu items also have a so-called callback data. The callback data is always used to pass a pointer to the object whose class member should be called. For example, the Print menu item has as callback function the Print function of ed/Editstubs and as callback data a pointer to a printer of class ed/Printer. In the stubs function Printer::Print is called.

You can also call functions via the other main window widgets, for instance the diagram name text field or the node and edge toggle buttons. This works similar as with menus. You have to supply a callback function (XtCallBack) after the widget creation. These callbacks are also listed in the stub classes.

4.3 Xlib drawing

This is a very short introduction to drawing lines etc. in Xlib. For the rest you are referred to the documentation mentioned in the references.

X has 16 drawing modes (so called raster operations). A technique for simulating graphical objects moving or stretching (like resizing a box or a ``rubber band'' line), is to set the Graphics Context to the eXclusive-OR raster operation mode. The Graphics Context is an Xlib data structure which determines how an object will be drawn when a drawing routine is called (XDrawLine, XDrawRectangle etc.). In XOR mode, the new destination pixel is produced by the exclusive or of the old destination pixel with the source pixel. In this mode, you can easily draw and erase a figure. You draw a figure to let it appear, and when you redraw it, you erase it. By sequencing drawing and redrawing you can simulating an object being moved or dragged. Furthermore, in XOR mode, objects can overlap each other without damaging each other. The overlapping part is then white, and when one of the objects is moved or removed it will be redrawn, so that the overlapping part will appear black again. All details of drawing graphics with Xlib is hidden in the XGrafport class. An XGrafport has as attributes some GCs.

Note that each Xlib drawing operation is performed twice: one on the drawing area (window) and one on a Pixmap that serves as a backup store. This is needed because X does not automatically save the window contents when the window is overlapped or resized.

All the entire Xlib drawing functionality is hidden in the ui/XGrafport class which is a descendant of the abstract ui/Grafport class. Because XGrafport only uses a reference to the X Display and an X Window it can be used rather easily in any 2D drawing program under X (it uses Xlib but it does not use Motif nor the other classes of libgui that use Motif).



Footnotes

... functions 4.1
`callback' is Motif-speak. `stub' is TCM-speak and means in this context the kind of callback function that is used in TCM and it forms an intermediate between the GUI (which uses X/Motif) and the other classes which do not depend on X/Motif.

next up previous contents
Next: 5. TCM Class Hierarchy Up: Toolkit for Conceptual Modeling Previous: 3. Source Code Organization
Henk van de Zandschulp
2003-01-07
tcm-2.20+TSQD.orig/doc/developersguide/developersguideimg14.gif0000755000175000017500000001002510077525341025231 0ustar otaviootavio00000000000000GIF89ayOOO---|||xxxllljjj```TTTHHH>>><<<000$$$ !,y@ dihlp,tmx|SpH,Ȥrl:ШtJZجv;qxL.4׫n|NO~wI A CB@AA @ yNJOΜҌ@ @Aș*H9+!+mAHOŠ&b8"GT?Tqd&S)V˗$Q¬#38sޜjfMQXaѡM"ms`ӥIBE4Q FQ(hn'% d9 R zr:-zm7K_|$ֶ0Ƹ F˘3p:Xㅔg3gah@#/,p@#|c8b BZ x Av["TB@PP a_ɑ/w:d`pBq =7@qoM@pH\ H5}Ua!!SgŒh{*"UJ%Aub9)b@-5;G8Mu$}L>) &IPEXոH#=U!5'$Hv@tl v N'g tʉY%-.KZ>*iUj饘f馜väIjʢJp&jhzųHe٥wjRtl:jlV-^KZqmGD;~ɥ%~Iqt^걻ԲKnL!pH< 7,ÎF,1/jkl )njyܒtLXe(_|LLG7wDnl•#irqIB~G! hR`nf%猐#*b`5bgS6Xی^RMl,v4e&wP(MnY D"s+y8/gq"ޙ>D%ܭ#J4r@$.[q!S'G<>KM<-}̣HPK:^T=  +59#X\(j 2/ #9ІMb8I: M&oY@THI"e%:M|7*ˊXd6 `H\sNh+h X0dv X=1e~)HWJ""!H(-r2#Hj0IIRRn'mUr73JE,{ H'N V"( !q)p0ht> 9A"}.auh9}DДH AhbV:)¨G[MhVZRHlUC׊Vqz͊>|_-a,,\X.Vt,Q#`K›zA6e cXl AҽaUōoHeVImGoWGG0`~$B,WWq\j8m5sݞM>z& v2-USHUuS"PzpˣB/ 0S`m.ރ!`N~@xg΁NoSKdM!Lg7V$` L,ʋo\" @@1ἒm`BكDM%1_L/V Ř "΍8 I Q>al5ٹukgܹ}MBЈNtfG93Σ#2aliJϾ-.2x/Dp#R巵6/5f 0Г!`{E>vl1b-nY6#m-{>CԭCjq=Wwz[QhvcY@]gGX~[knϹSSxϻ+Pz(UBn"Y܆mթ3='$(}.$rtQwE5W=hW#keȄa_%?HA(ÆZ Pl̓s8aUq8j% EwhmGR,@d1v/#$%V/C+'04]rWB+\kH =$pkXahn !=kE0+@SpB(bq_{wUy8}g txVxƍ捰EdyS⇛3XV`[xw"xPd8l jn h 9n<nXDHq yۨ[&y'9ƒ= *9)YK`c2GG4Ag0sROy8La&Bf~PB(ZxTQ27qP{{U '{ 7|&UbY}(''Ra GpUzi|I PcT~Zځb0Փ2Vpf" p'K7R <u]LG]I31iZl|.nZxRqUْW@Zajv3KJ #9@Ie)4]6 CƉ0i|ָؠ50ws4fZ7T؁ynڜVIl(:嶢yE1j`@0qR'S5:jBYŚqgY'A>RAl YХ[Z C4JXeZhqU: T%WAZwv cZBpbU^.{Y R4UbRkSQ%6X~F5rE+4)O3{2C&t9at@?m2c> J x>@tz7Pd!ʂ,xj3z*ّ~1itCzID4{  EU"Rn,R夑@]EPYw{GZpSM*g=\jeB-[(k@yCЧ}ԗ/"'#Ui* \ݧ w b0NUZ甗)^ lҪ\k Q ʛ᫫ʷ P5IwFy&A|Y5jSu*$vk K;Q{{ۺ$!;tcm-2.20+TSQD.orig/doc/developersguide/developersguidenode4.html0000755000175000017500000006314710077525341025535 0ustar otaviootavio00000000000000 3. Source Code Organization next up previous contents
Next: 4. TCM User Interface Up: Toolkit for Conceptual Modeling Previous: 2. System Architecture

Subsections

   
3. Source Code Organization

3.1 Source code versus design criteria


  
Figure 3.1: Logical source code organization.
\includegraphics[width=5in]{p/src-organization.eps}

In this chapter we explain how the source code of TCM is organized. TCM basically consists of about two dozen graphical editors and a startup program. The source code can be found in the directory $TCM_HOME/src. The TCM source code is physically split over several subdirectories. The sources can be compiled into a number of object libraries and executables. The source code is split in order to factor out commonalities between the programs. See figure 3.1 for a Venn-diagram like overview of the commonalities of the source code. The entire TCM source is called Global, the sources of the programs that have an X/Motif GUI, are called GUI. The sources that are used in all editors, are called Editor. The sources that are used in all diagram editors, are called Diagram. The sources that are used in all table editors are called Table. The sources that are used in the editor TERD are called TERD etc. For instance, the editor TSSD uses the sources of the TSSD area, the TERD area, Diagram, Editor and Global, but it does not use Table or TCRD. See figure 3.2 for an overview of the current TCM development directory structure. The sources are physically split over several subdirectories of the src directory. This is done according to the following criteria:
  • All code that is global and that is not part of the other areas is collected in the directory src/gl. This code is compiled into a library called libglobal. This includes common classes for lists, strings, Unix utilities etc. that can be used in any program, not necessarily a TCM tool.

  • All code that comprises the graphical user interface but which is not specific for any TCM program is collected in the directory src/ui. This code is compiled into a library called libgui. This includes a generic application framework for Motif based C++ programs, classes for drawing lines and other shapes under X, classes for building all kinds of pop-up dialog windows, classes for making various pop-up and pull-down menus etc.

  • All code that lies in the editor area (and in the TCM area) but not in one of the subareas, is collected in the directory src/ed. This code is compiled into a library called libeditor and in the executable tcm, the startup program. The libeditor library includes things that are applicable to all TCM editors such as saving and loading documents (the generic part of it), printing documents, the on-line help and it contains a number of abstract classes like Document, Viewer and Command on which specific editor classes are based.

  • All code that lies in the diagram area and that is not part of one of the diagram subareas, is collected in directory src/dg. This code is compiled into a library called libdiagram. This includes classes for (abstract) graphs (and classes for nodes and edges), classes for graphical shapes (boxes, lines, ellipses) and classes for most diagram edit commands (CreateNodeCmd, CreateEdgeCmd, DeleteShapesCmd,...). This library is used by every specific diagram editor.

  • All code that lies in the table area is collected in directory src/tb. This code is compiled into a library called libtable. This includes classes for (abstract) tables having rows and columns of cells and it includes all the table edit commands. This library is used by each table editor.

  • All code that is specific one or more (but not all) of the diagram editors, is collected in the directory src/sd (specific diagram). Each specific diagram editor can be compiled into a distinct executable (at least in principle, it is also possible to compile more editors into one executable). As you can see in the picture, the code of some editors includes the code of others (e.g. TSSD code includes TERD specific code). The specific diagram editor code consists of C++ classes derived from (possibly abstract) classes in libdiagram or from other specific diagram editor classes. These classes are (indirectly) derived of the libdiagram classes Graph, DiagramWindow, DiagramChecks, DiagramViewer, Diagram, Shape, ShapeView, Node and Edge. The tool specific constraints are all implemented in the classes derived from Graph, DiagramChecks, Node and Edge. Because the specific diagram editor code is so diverse it is subdivided further into separate subdirectories:
    • src/sd/bv is for the behavior view editors (TSTD, TATD, TRPG, TPSD),
    • src/sd/dv is for the data view editors (TERD, TESD, TSSD, TCRD, TUCD),
    • src/sd/fv is for the function view editors (TDFD, TEFD, TSND),
    • src/sd/pv is for the physical view editors (TCPD, TDPD),
    • src/sd/gd is for TGD and
    • src/sd/tr is for the tree editors (TGTT, TFRT).
    The TGD sources form the most simple diagram editor and it can be used as a basis for developing your own diagram editors. Specific editors that reside in the same directory can share one or more classes (for instance, the class BinaryRelationship is used both by TSSD and TUCD), or, one editor shares/extends all classes of another editor (for instance, the classes of TFRT are all specializations of the classes of TGTT).

  • All code that is specific for the different table editors, is collected in the directory src/st. The amount of specific table code is rather small. The specific code consists entirely of specializations of the following classes in libtable: TableWindow, TableViewer and Table. Also, most of the tool specific constraints are implemented in these specializations of class Table.

In principle each C++ class is declared in a distinct header file and has a distinct source file for the implementation. The files names are equal to the class name except that file names are in lower case letters by convention. Header files have suffix '.h' and source file have suffix '.c'. The reason that C++ source files have suffix '.c', which is originally used only for C programs, is that some C++ compilers require a suffix '.C', and some require '.cc' or '.cpp'. There is no C++ file name suffix that is accepted by all compilers that we have used except the '.c' suffix.


  
Figure 3.2: TCM directory tree.
\includegraphics[width=4.5in]{p/tcm-distribution.eps}

  
3.2 Individual files and directories

In the previous section we described the contents of the src subdirectory. Here we will describe the individual files and directories that are included in the source code distributions of TCM. The TCM distribution top-level directory contains the following files:

  • CHANGELOG, which contains the differences between the consecutive TCM versions.
  • COPYING, which is the GNU public license.
  • FILEMAP, which lists and describes the files and directories in the TCM executable distributions.
  • INSTALL, which tells how to install the binary and source code distributions.
  • MANIFEST, which lists all files and directories in the TCM distribution.
  • Makefile, which is the top-level Makefile. Most sub(sub)directories contain a Makefile too. See chapter 7 for what to do with these Makefiles.
  • README, which is the README file about the TCM project, the software, manuals, distributions etc.
  • tcm.lsm is a file that describes TCM in the format that is required by the Linux software map. TCM is registered in the LSM (http://www.execpc.com/lsm/).
  • tcm-dynmotif-2.0.spec. RPM spec file for building a TCM RPM distribution that links dynamically with the Motif/LessTif library. You can use (a modified copy of) this spec-file to build your own TCM RPMs. See http://www.rpg.org for more information about RPMs.
  • tcm-statmotif-2.0.spec. RPM spec file for building a TCM RPM distribution that is statically linked with a Motif library.

The top-level directory contains the following directories:

  • bin/. Here the TCM editors and other binaries are put after compilation. Also this directory contains a number of utility programs:
    • bin/mkbindist. This is a shell script that makes a tar.gz file of a binary distribution of the compiled source code. The script needs two arguments for the version number and the platform, e.g. mkbindist 2.0 solaris.sparc. This will create the file tcm-2.0.bin.solaris.sparc.tar.gz in $TCM_HOME. The files that will be included are listed in the code of the script itself.
    • bin/mksrcdist. This is a shell script that makes a tar.gz file of the source code. It needs one argument for the version number, e.g. mksrcdist 2.0. This will create the file tcm-2.0.src.tar.gz in $TCM_HOME. The files that will be included are listed in the code of the script itself.
    • bin/mkclasslist. This is a shell script that writes the names of all header files of the source code to standard output in alphabetical order.
    • bin/psf. This is a Perl script that is used to filter PostScript output (see man psf).

  • doc/. Here all technical and user documentation can be found. The documentation is in HTML-format and possibly in PostScript and/or PDF format. The file doc/index.html links to all the different HTML documents. The documentation includes:

    • User's guide. In usersguide/index.html you can find an HTML version. A PostScript version can be found in usersguide-2.0.ps.gz (large PostScript files in TCM are always gzipped to save disk space). Optionally a PDF copy is put in doc/usersguide-2.0.pdf
    • Developer's guide, which is the document that you are reading now. In
      developersguide/index.html you can find an HTML version. A gzipped PostScript version can be found in developersguide-2.0.ps.gz. Optionally a PDF copy is found in developersguide-2.0.pdf
    • Source code documentation. For each C++ class an HTML page is generated by the program DOC++ (see chapter 5). The HTML index is in sourcecode/index.html. Also a PostScript document with all the source code documentation can be found in sourcecode-2.0.ps.gz
    • Specifications. The directory specifications contains a number of specifications (made with TCM) of some individual editors.
    • Wish lists. The directory wishlist contains:
    • Document sources. In the directory docsrc you can find the LATEX, EPS and TCM files that comprise the sources of the documentation. These files are not included in the source code distribution itself. The sources can be downloaded separately from our FTP-site, from a file tcm-2.0.docsrc.tar.gz The sources contain a number of Makefiles to generate a number of documents automatically. The program DOC++ is used to generate HTML and LATEX from the C++ source code, LATEX2HTML is used to generate the HTML versions of the user's and developer's guide. We have included the sources of DOC++, so that it will be compiled and installed before you build the documentation. LATEX2HTML can be downloaded from ftp.tex.ac.uk/tex-archive/support/latex2html LATEX2HTML is written in Perl and you have to configure it yourself before you can use it on your system. This is all explained in the README file of LATEX2HTML.

  • lib/. Here the object libraries (libglobal, libgui, libeditor, libdiagram and libtable) are stored after compilation. Furthermore this directory contains:
    • lib/TCM is the X Resources file. This file is not directly used by TCM (the default X resources of TCM are included in the source code), but it serves as a basis of your own modifications. You can load X resources with the xrdb command or by including them in some X-startup file like $HOME/.Xdefaults.
    • lib/banner.ps is a PostScript banner page. Normally this page is not printed but when you wish to print this banner page in front of your TCM documents, you can indicate this via the Printer Options sub-menu of in your editor or you can make this option the default by updating the tcm.conf file.
    • lib/colorrgb.txt is an ASCII file that maps TCM color names to red-green-blue (rgb) values.
    • lib/help/ is a directory with the on-line help text files. The help files are all in ASCII format. These help texts are shown by the commands of the help-menu in the editors.
    • lib/tcm.conf is the TCM configuration file that is read upon start-up. It contains also some platform specific configuration options, like the name of the printer and the command to print or preview files. This file is intended to be human-readable and self-documenting. In stead of editing this file (which will affect all users of this TCM installation), you can also decide to override one or more options in a personal configuration file $HOME/.tcmrc. .tcmrc has the same syntax as tcm.conf. Note that some system specific configuration options such as the command to print or preview a document is commented out in tcm.conf. That is because TCM itself tries to determine these commands. Only if TCM can't find these commands or it chooses the wrong ones, you should set these as options explicitly by modifying tcm.conf.

  • man/ contains Unix man pages for TCM.
    • man/man1/ contains short manual pages in nroff-format for each of the editors.
    • man/windex contains a simple index file that is used by whatis and man -k.

3.3 Object libraries

Depending on the operating system and the way TCM is compiled, object libraries are either shared object libraries, ending on .so or object archive libraries ending on .a. In the first case, the object code in the library is kept separated from the tool executables (they are dynamically linked), which makes executables smaller and run faster. For the Sun CC compiler (the default Solaris compiler) shared object libraries are made by default. For the other compilers such as gcc archive libraries are made by default. The contents of archive libraries are physically made part of the tool executables (they are statically linked); the libraries could be removed when compilation is completed.

Executables using object archive libraries tend to be much larger than with shared object libraries. Because of that, distributions that have to use archive libraries are in general compiled into only a few different executables, e.g. one for the tcm startup tool, one for all the diagram editors and one for all the table editors. The individual editors are then symbolic links to the collective diagram or table editor. The collective editor will see in its argv[0] argument which of the tools has to be launched.


next up previous contents
Next: 4. TCM User Interface Up: Toolkit for Conceptual Modeling Previous: 2. System Architecture
Henk van de Zandschulp
2003-01-07
tcm-2.20+TSQD.orig/doc/developersguide/developersguideimg5.gif0000755000175000017500000004655610077525341025173 0ustar otaviootavio00000000000000GIF89aY}}}eee---''' xxxllljjjhhh```^^^TTTHHH<<<:::000***$$$ !,Y@&dih p,tmx|pH,Ȥrl[Шt PجvzxL.h+mM|NYlzdkje]" [wYR ~Z_l#"$ &.׼pmӹg"  '0-qػ)X0 Hwș2 }$PȐaB'$ @iB bB0($g'O>=gf:aACR6ܜB4LP/WDV<_z kQ +˂qҖ`;Ɗݱm@`Ɠe6eV>,b=\!^ԥ+^$hX@1UˣS6`D Ţޜjx /Vi.t4K'?m-7z89I34,v.RkkbX@%}\,Zy$&?i&!xF}Ї(mpc%1~>cL7^+:i#!=pGХ.qgf!4tT/$SPɹYJ #(FE e;X1h7WIol2 |?I/H1kCJ Y3DFk?,n=LLz.ܨJWKs,Ġ ֑U])>WSH" ~/Ӡ;ROgLtF27*Kj#uԈfh@I&PIk<˺͌(q彔n^#׽2~ @Tp9 =b$;mO*ʔJ-,&Jjv_hcI,$\UhPJ!d*[DV k#cu\(pY:VkjLVe. 1VyD]bwaěmKzRdxJ_|j^*M~37BRgۈTG׿[<03 Z J!N IK y=r&:SFO4YpW$TT)3!:SO,}3 9ľdJaH`@@1@RDVb\d҅ bZ 4rƋa岢I ?L1LJ[*9}^HVB \5Q[Q|NjggF ʤr6~Wi$'q -lZ7t  jHZH7qp^pe=[E5Ic OSVOSS!FK=Go8Y6=ïD܇ן8}*lag8L׀g!N/PJx˧Ł@ "8$X&7T,e2P0Xtn$@~e>h'gVCJew'@Ų[qz.6FKxb`e Ru=dnW:؅d6eȃaYpru{-&6[VGP'~4hY~xI}'I†d vb|Rأ=8wM1SJ<.wMM4m&m@aU8E;O3bUb- b6klpgu6W\Ҩ qR+FKhW(`k%a8''wu((Ggbr(0QhrTW*d855~U{5M! g&8؈D& $9zKVg8y'ǀb^quVxg~ ,W G{ȉ|`4:v8aBYF$}$)W8&C\YȊ|m5@Mi PA0 /yi-T.NYzE.wF(asZ>#8[Qؗ[z#(wwiZZ}jl9x؆q) h(%Ye2q"c: `rOdy!X"{‰;Ԣ B={(Ajڅ}G&Є)'Tfy"/O{ ziu`~x*Zh?I>9; SN[, " jO>U[q2ꡣ@hX.@"M.cנ*cq4',X!Jip֔`|shɓ,HKDRE\LyZi~sDI,hNj%z)dJ1p~e5ꂌ:zj{%F*/p52Yv0 eЧjA^#Anٝmۅ~C 9jZ$ȑ3hE6ӄ$ X) a:Dr|V2Z%4(('@zUZʪ9)_jDZTnXΐxW1ЎtGusW8wx}P))KWv:UXH)(ZV'́!f ' }4mozĶ> $ClEÝD {Zįk@ X xmf^Af\ixQiZ|Ī` (K1 Ƥ I*a Pn;%1kիL3Z i𛴻J:uiTO|˽ݛQ4N]sÝTvg#˞?vj' !' pAv=gȳ Zp@u,˨FMj9bIDQ,΀\Pެ#,ÕlqXRÚ,ͼɼZ$:L#; N,bkr,)cњƗF$ٵ4XKzŬ> ՆVȼ"ݨ"-XyYĨmP ӗ1r|A;Mt<{pV#i)M6,Пaj[e;8ɡG;UɐU^ĴK?l*AqӸGٓ=U9a%1{*_u,U. +-qK> `ɨq(Օm,;}& ]r+ђиԤ}XZ pa~H{ѹ Xy0ɱ٪;]=X~}g %5:*k%{B5P[`؞Z ,p-4~]8< d g3bLEi}J~㙝OupUn媵)2P^>su5]w2}g[ |yt!=UR]]2R-mێCeI{>W>zϸmh>nFy4ln<>ؘ>EAD 0;4 XsӀ6̊͘V܀w[kz p0p+>pl.tm'*'ĺ)] {ކQ ξ~O]fLj2xMS>>KNst|=RP[-F i׊CuNZd!5tSA0͕p7Xzt sޱb9`>X~Ҽy`r.D(RnH\5P=eՊ6c+CoMZ mM0r6<0Wo`¿vZg)d3% > k_a1^dygxm*RJR)UhhGN 4 7IaIn 5ɂq.`NVZ0ަ?7Ie Y0RI GNv 3ֈ?BX!sgA`y=6 ]RwPO_nnq@2J )h LTlj2 UA_z{Q h^IڝD&ЫIAN9k LA ("ʞH9Gyfh'. $Z^VaLB]VخvBm^2,Vp20onOZzS"p)`їrs0Z?Ujc;-@x/k&$BV?AX$g ZBؕ!{k~,<)̅6k FߺGBoH؎sd[q7 h^pӚƜ1Rl[ܔ4 :H[#fQlx &eOÞ)͙@N$+gG`jDXB$1m.J@J (I=0R/ew\10 h$ʆR#x$-k Mu# ;2$+RL_9KYC2s6cDMp%܈ g8D6EP\<u>!J= " 4(o R/5ː1ʌ(Pp+D`HL(j0HꇤӻtGM;Z!wD-PV/B n\p7پj`5+>':ԛnփ Y@L U\(pBCl49Eћmn)7ò'f)v@HԂ&8ﰵ&C Q(jiKY `38]ЀGpNlSUjq*xqP"v0VvVnWˎorh@iF.ɕoNMJY lv\ pa{W yGQVr8=0 `L3*D϶xN{<xCO &v,<_4i|ܞ=+6R֓_ 8A~jyn&nUBWo"#>-4o^b+마W&Z4.`R%_%˙>5$|Y+@GQ-녪LhDz־XK$9D_3;mXfnn#+SbXq 2Bu!_7 J{klK&o8ǶAë?K;ʝD[O %eml\ 2ݚÇM,A q>úu0-_qR5]ꂚ sg87D9p N77S: uYNs(۞;߃NdمH|?\n(`;#Uz< A뜿F ]wv>n=셮ؒJTc{Y1;7Ƚ#M|/x=7]+)>PZ7[۞;ɺ@.E>ŞO `Ο.5`= NrU 9= j `fUי q ݕ u``=^( N Ҡ ` &%S@TY {])AI *GDj5!R_RɆڝGlɀCX|}\ 8-!nA]R-RǸ[ ZKm(E*=Ug}$a!rX`ba(2 XWO&X4T^pƢj\ DR(b#j2>Z"Dia/ @͍kXY Xc!aB2DH֌̠@. ]h#&O#L?X!#:NSW @#!#}1&փJC8Y%>#֕4,[<- x*l@@D LP,a)E-8Y2b7C6#,K%L&%KEBAA[Oʁ[4uee7TY$Cml ,IЈ$ 'xHSvdeF d܊Aza!a^eU h@S>Z:EY$TFHA|3.*% c/d%A0Tg WJT$@gnEn'wsMwNDFnpwRe[<C^rR{6?gh>Bu(Bo(N{fsΣ\ff(t s]R2Hҽ}FJhoZѥ^~1G= ~h I+Й F{yd&Ie2 ]'v>4oI!&VRU~h'fXiؔlhP1Yh 4^M\fxƩ)֩@DDZn @pU}߅:W.]2&*eVּ9i"$CejM )1fRg**j3@)ʸ,J-tQH~*\Fe% K* :H֤:9K$in*by9bzb*#G~e^+v]ir~*x2(4@>vz<(bdסݹVS2蠠B,뼮f߬k&or7A39&=*JkhHnJBRxk,%6~0El^ Zr+~XV"Yg9nludfƪ*V~DU֖(ښF]k<.rd^#De+ '.u- o,kԧj+.7noA ߦ$$]oBoRF߆̢k '!peJ6O,w_,ii ^$g I0ƀ b /lס$, "d &q-1;/ƇS\j]r1a81 C`$$bӱzq`1 rņ(!2)"/Vj+#?&)$Oת+%.%[_, F&o'[O-7r$.rLrQE$) ,_B,7r.,2i2oW'0@St/03s.r:*q50pP%5Bq72KZ??1ts.k7w%M3=k"-AF??GNq- _p"'4E!C瑑S/'S+,r-{t9r5`@CVBtvEKSf 2N30O mA -l,S7S?5 DKFQz|9TsFHs6_:ϫXe/:=o)գ\W' iZ2:m5Ro}i(-K\rK8Uv496vYْۢZ@b@rNufK? $/}@**3JhR3QV5unhA[`n?F ܦtH/vj7j/i"u-pO@A$ unwޖ6MR|4^rKwQ$td2}(Fe+6]3Ti'v |2C3ã*qDټc6fH ŷ0#Ay9Azz}ޱhIҿtC=Ŀe)~uO[7-dvKg\՗9.{Yb{zv|ϗ=׹7Iǧ+ <4Я|p=+>Q=Kd@~ԛx\\9fKrki=):oڻ;nӛ= y!>rm@'3(5\F2=) 3ZpeQH3XH`*)RL> [p5$qYlZD^5( ̊Wb g궊m0gFg%DcAADhh !wy)iixJ:#ZjszH6 薴Ԅ,,z8X ,h!쓇iMAvM =k^i @*3hh;&^:\8 %PPX&AFR$h`o6A)eÇhiͩG*|`-AYg<^J|tͨr:dQ3H`Ti{/P Pi;Zx7Fkz95K IMixfe"mo$HYV|X9( a %cMY@t{nt00l,d l~2btްiB!Z>: 9B)H,͎JlJ7kO+7hG0]kl]^"j8HؒkƸ~'ldڨBnrMx1npZ}<<0`2RGT$xUrt2y2 F\|ud8evYձY`E8%!!k+"rDT^RYRvc 5d0K :kg n5*d@yb?wh/`sPTլ,Yldkite%.'Xri lL3o.Kk3#9w8{Mva 惢=Ll&;ի|w!:5ӵ 7{=,gOwmqs(MF0pN'.s"+ oq^e"f{y/9{nAv|2iZRwgUduzEK1%F:Ü5z1V8Ɣ9ybvK^b nˎJ-Lh 7ncj [Nv,Xμ)erV4W|AE&Wؕ>־C|ɳ:A:Ix'6VgEuuGL6uP1ݰ_~^54 `WQd?!U{gvW|"|}Hj$Vs#5|'}wا,^~u'&|<~敁ŷ$s~!(dVsgwz)X~8X G1&us6qݧDa (gUG{؄5x`Ht w:qXh|Eh7V}JV@-Vy(x*~sfo(t =P$p hWŲZ7[H|Ԇ @XUȇ7L}efeQ?L#dPEAjx)@(;`4d6.BO6B*0nxq}5E¸t%8mf@NbCWxyD o8(3ָ__h&EUyw&@Fx% Fgj'Bz6hf؏5΀vM1W)<u6i&XɄ> g@@~$VY2H !FϦ# p&W: s40(S w1@ $Ay"+fLCwYctؕ^)`N7ZEMw|lymN4P9YjQVGydn7jxH%t:`kxZz=9!@ХG^tW~7uCX[27b4eQK{QzDTI dPwo2晤YIk&rY8U HF"5Q4P \D z@9uyTI9hrb З9eN;I' \#_9I{#`i[jL*o_'wuz)))]Ƣ5 &rף :il9\1rsjLZYD4báD/y0ZP1@VZH2HX8iy` 0i_S4k T%p'< eڙ)ʃ'i3g|WoڧBʏ(C?Yvj#Ӟw 4F(S9j Rɬׁ0 b0IzڬZ ׌ݾݸjlKP++-ͺ/9;=? A-C,M4;G>Vl L.9FnJN[}U$^eNI)~Qni7Юub^TL{^Y䃾T-NO.~N.}cnn4l_鄞=r~>[a^N'N} 鮎ɨDZꬥe\}^LOP iqhez1 NA50يR<|DdqNsqLCa}s^,f2 CU/~ U'%ٶ|ӹ/4e3.%}w&_CM.-M qH5~"_s _lg .:[c!WtSfK~]LW| Deݤe FSBɎ+ {utڇpk(r<_`s?1K~ 7Sf'Q]o AS"owoqkcc nHݚ)LZu&]//ּ#p8*+#\:) Lvqʭ-Rʆj!(dhH+h|B)bֵ1 *./E°$R?,1j!B1n@H48*VΜdjRNbAJzYq`$H hX,H`Ƣd,lL½HlfZ!-Xi`d\& `f2Z'7ǒ MoHLl,7"ʣ vΓ*4HXZk!LO(u5h PUd`AȂJ@53e*_ LДYPbGN/L@ѦJ &eT+T\J`KftԪgbǭ*0!2 Pl2VZ LZ 1W# 2sA‚Ά8ⶀ3ݖgV0;AZA10EgTŭr5@XCdLp@q>)3kXM(:LqwosGntL^f(Ex=|i`"GbcZqR5tyxvdlhR Iؑ;#iS}$E]e1j5y_/YyՅ,Tޅ*P1"PMi~ȓc<z'H@7V(yJ "aI 8ZA+ !*6$ t؁ǝ$+agoWjIivJ*MkewV3 y㴼NV+S 8 L)kՎ 2BKĊ)InP1L X ;ur;ňf»y\9ʜur̺Q)2Dz .93&s|" [+ļ/(9BkL4:ln@?ԂnЭU}ԋt،];8,Q .,-uiP>D,Un0TŒ z8f?h3D1$kOD?1w>F픉|A/cjk @ ?g>2YR\)/x; $ l…K?:n2lb-NVd d$ + ƻBX @@"t\d< %xHBѸ c3.