summaryrefslogblamecommitdiffstats
path: root/game/build/tools/mksnt/ugrep.ksh
blob: 461322aa640375fbe6b9d2d7606f39b5a682ba18 (plain) (tree)








































































































































































































































































































































































































                                                                                                              
# UltraGrep - A find/grep dlg example.
#
# This shell script accepts user input from a dialog box, then runs
# 'find <directory> -name <filemask> | xargs grep <grep options> <pattern>'
# The output from this command is piped into a results dialog box, which
# the user can then browse through.
#
# Useful for searching through a tree of source files for keywords, e.g.
# 'find c:/msvc20/samples/win32 -name "*.cpp" | xargs grep GetOpenFileName'

# Dialog resources are included at the end of this file
RES=$(whence "$0")

# Here are some constants for the controls used in the 2 dialogs
IDOK=1
IDCANCEL=2

IDC_PATTERN=10
IDC_FILES=11
IDC_DIRECTORY=12
IDC_BROWSE=13
IDC_NOT_PATTERN=15
IDC_ENTIRE_LINE=16
IDC_IGNORE_CASE=17
IDC_DIR_ALWAYS=14
IDC_DIR_NEVER=18
IDC_DIR_TO=19
IDC_DIR_TO_EDIT=20
IDC_LISTBOX=101
IDC_EDIT=102

# Here are some strings we use to store the directory setting in the Registry
DirKey='HKEY_CURRENT_USER\Software\Mortice Kern Systems\Toolkit\UltraGrep'
DirKeyName='Starting Directory'

# Make these variables into integers to make math faster
typeset -i count width height dlgwidth dlgheight
count=0

# This function is called from the second dialog loop, when a user double
# clicks on a line or presses the 'Edit File' button.
function edit_file
{
	# Get the current listbox selection
	dlg getcursel -c $IDC_LISTBOX index
	if [ index -ne -1 ]
	then
		# If there is a current selection, get the filename and
		# line number for that selection, and run 'vi' on the
		# file.  The -c option causes vi to jump to the specified
		# line number.
		dlg gettext -c $IDC_LISTBOX -i $index filename lineno
		start vi -c"$lineno" \"$filename\"
	fi
}

# This function resizes the controls in the results dialog, so when the
# user resized the dialog, the controls move to fill the space.
function resize_results
{
	dlg getpos -w dlgwidth -h dlgheight
	dlg getpos -c $IDC_LISTBOX -x xpos -y ypos -w width -h height
	width=$dlgwidth-30
	height=$dlgheight-85
	dlg setpos -c $IDC_LISTBOX -x $xpos -y $ypos -w $width -h $height
	width=$width-66
	height=$height+25
	dlg setpos -c $IDOK -x $width -y $height
	width=$width-90
	dlg setpos -c $IDC_EDIT -x $width -y $height
}

# This is where the program really begins.  Load the first dialog to query
# the user.
if ! dlg load -x -1 -y -1 "$RES" DIALOG_1
then
	exit
fi

# Add some common file types to the 'pattern' combo box
dlg addtext -c $IDC_FILES "*"
dlg addtext -c $IDC_FILES "*.awk"
dlg addtext -c $IDC_FILES "*.c*"
dlg addtext -c $IDC_FILES "*.c"
dlg addtext -c $IDC_FILES "*.h"
dlg addtext -c $IDC_FILES "*.h*"
dlg addtext -c $IDC_FILES "*.ksh"
dlg addtext -c $IDC_FILES "*.mk"
dlg addtext -c $IDC_FILES "*.txt"
dlg setcursel -c $IDC_FILES -i 0

# Set the default starting directory.  We might have saved an old value in
# the registry, so try to get it.
directory="$(registry -p -r -k "$DirKey" -n "$DirKeyName" 2>nul)"
if [ $? -ne 0 ]
then
	# Set the default directory to the current directory
	directory="$PWD"
fi
dlg settext -c $IDC_DIRECTORY "$directory"

dlg checkbutton -c $IDC_DIR_ALWAYS 1

# This is the event loop for the first dialog.  We keep going until the
# user hits 'Ok' or 'Cancel'.
while dlg event msg control; do
	case $control in
	$IDC_BROWSE)
		# The user hit the 'Browse' button, so bring 
		# up a directory browser
		directory="$(filebox -D)"
		if [ $? -eq 0 ]
		then
			dlg settext -c 12 "$directory"
		fi 
		# Get rid of any pending messages
		dlg event flush ;;
	$IDCANCEL)
		# The user hit 'Cancel'
		dlg close
		exit ;;
	$IDOK)
		# The user hit 'OK'.  We need to validate all of the input
		# before we can continue.

		# Get the search pattern
		dlg gettext -c $IDC_PATTERN pattern
		if [ -z "$pattern" ]
		then
			msgbox -i exclamation "UltraGrep" "You must specify a pattern to grep for."
			dlg setfocus -c $IDC_PATTERN
			continue
		fi

		# Get the file pattern
		dlg gettext -c $IDC_FILES files
		if [ -z "$files" ]
		then
			msgbox -i exclamation "UltraGrep" "You must specify a filename pattern to search for."
			dlg setfocus -c $IDC_FILES
			continue
		fi

		# Get the starting directory
		dlg gettext -c $IDC_DIRECTORY directory
		if [ -z "$directory" ]
		then
			msgbox -i exclamation "UltraGrep" "You must specify a starting directory."
			dlg setfocus -c $IDC_DIRECTORY
			continue
		elif [ ! -d "$directory" ]
		then
			msgbox -i exclamation "UltraGrep" "The directory you specified does not exist."
			dlg setfocus -c $IDC_DIRECTORY
			continue
		fi

		# Save the directory settting in the registry
		registry -s -k "$DirKey" -n "$DirKeyName" -v "$directory" 2>nul

		# Get the options for grep
		if { dlg isbuttonchecked -c $IDC_NOT_PATTERN result; test result -eq 1; }
		then
			grepopts=-v
		fi
		if { dlg isbuttonchecked -c $IDC_ENTIRE_LINE result; test result -eq 1; }
		then
			grepopts="$grepopts -x"
		fi
		if { dlg isbuttonchecked -c $IDC_IGNORE_CASE result; test result -eq 1; }
		then
			grepopts="$grepopts -i"
		fi

		# Get the options for find
		if { dlg isbuttonchecked -c $IDC_DIR_NEVER result; test result -eq 1; }
		then
			findopts="-level 0"
		elif { dlg isbuttonchecked -c $IDC_DIR_TO result; test result -eq 1; }
		then
			dlg gettext -c $IDC_DIR_TO_EDIT result
			if [ -z $result ]
			then
				msgbox -i exclamation "UltraGrep" "You must specifiy a valid level number."
				dlg setfocus -c $IDC_DIR_TO_EDIT
				continue
			elif [ $result -lt 0 ]
			then
				msgbox -i exclamation "UltraGrep" "You must specifiy a valid level number."
				dlg setfocus -c $IDC_DIR_TO_EDIT
				continue
			else
				findopts="-level $result"
			fi
		fi

		break ;;
	esac
done

# Close the query dialog
dlg close

# Load up the results dialog
if ! dlg load -x -1 -y -1 "$RES" DIALOG_2
then
	exit
fi

# Add the columns to the list box, and size the controls to
# fit the size of the dialog.
dlg columns -c $IDC_LISTBOX File 200 "Line #" 50 Result 200
resize_results

dlg settext "UltraGrep - Searching..."

# This is where the actual command gets run.  We want the user to be able 
# to cancel the find by pressing the 'Cancel' button on the results dialog,
# so run it as a co-process, using dlg -P -W to read the output.
# To get grep to output the filename every time, it needs 2 input files, so
# give it 'nul' as the second file.

exec 2>nul
find "$directory" $findopts -type f -name "$files" -exec grep -n $grepopts "$pattern" {} nul \; |&

# Set the shell's input field separator so we can parse the output from
# grep easily.
OIFS="$IFS"
IFS=:

# Start the event loop for the results dialog.  Remember we started the
# command as a co-process, so we use the -P and -W flags on 'dlg event'
# to read the results from the co-process.  This loop will continue until
# our co-process finishes, or the user hits 'Cancel'.

while dlg event -P -W msg control; do

	case $msg in
	coprocess)
		# We got some data from the co-process, which will be output
		# from our grep command.

		# The output from grep looks like this:
		# <filename>:<line number>:<matching line>
		#
		# If we specified a full directory name to search from 
		# (e.g. "c:/msvc20/samples/win32"), the colon in the drive
		# specifier is going to confuse the shell, because we've 
		# set IFS=:.  So if the filename has a drive specifier, 
		# we need to parse the output from grep slightly differently.

		if [ "${directory#?:}" = "$directory" ]
		then
			read -p -r filename lineno match || break
			dlg addtext -c $IDC_LISTBOX "$filename" "$lineno" "$match"
		else
			read -p -r drive filename lineno match || break
			# Reconstruct the filename
			filename="$drive":"$filename"
			dlg addtext -c $IDC_LISTBOX "$filename" "$lineno" "$match"
		fi
		count=$count+1 ;;

	child-exit)
		# Our co-process is done.
		break ;;

	break)
		break ;;

	size)
		resize_results ;;

	command)
		case $control in
		$IDOK)
			# The user pressed 'Cancel'
			break ;;

		esac ;;
	esac
done
IFS="$OIFS"

# Make sure our co-process process is dead.
kill %1 
wait

# Change the title and the name of the 'Cancel' button on the results
# dialog.
dlg settext "UltraGrep Results - $count file(s) found"
dlg settext -c $IDOK Close
dlg enabled -c $IDC_EDIT 1

# Now we start another event loop on the results dialog, which allows the
# user to browse through the results of the command.

while dlg event msg control; do
	
	case $msg in
	command)
		case $control in
		$IDOK)
			break ;;

		$IDC_EDIT)
			edit_file ;;

		esac ;;

	double)
		# The user double clicked on the list box, which
		# is the same as clicking 'Edit File'
		edit_file ;;

	size)
		# The user resized the frame so resize 
		# our child windows to fit
		resize_results ;;

	esac
done

dlg close

# That's all folks.

# Dialog resources follow this line
#[]mks internal resource : dialog : DIALOG_1
#[ ]begin : size 1012
#[  ]MP #(D      3 !< %0#Y (X      %4 ; !T '( 80!' '( 90!P    " !-
#[  ]M %, ( !3 &$ ;@!S "  4P!E '( :0!F       "4      +  H )@ ( /__
#[  ]M__^" "8 4P!E &$ <@!C &@ ( !& &\ <@ Z            @5      -0 (
#[  ]M 'P #  * /__@0            )0      L 'P!C  @ _____X( 20!N "  
#[  ]M1@!I &P 90!S "  30!A '0 8P!H &D ;@!G "  = !H &4 (  F %  80!T
#[  ]M '0 90!R &X .@       @(A4     !R !P 0  \  L __^%            
#[  ]M E      "P V #( " #_____@@!3 '0 80!R '0 :0!N &< (  F $8 <@!O
#[  ]M &T .@        "!4      ^ #4 <P ,  P __^!          $  5      
#[  ]MO@ & #( #@ ! /__@ !/ $L            !4     "^ !@ ,@ .  ( __^ 
#[  ]M $, 80!N &, 90!L             5      O@ T #( #@ - /__@  F $( 
#[  ]M<@!O '< <P!E "X +@ N          <  %      !P!/ (@ -P#_____@ !-
#[  ]M &$ = !C &@ :0!N &< ( !/ '  = !I &\ ;@!S          ,  5      
#[  ]M#0!; 'X #  / /__@  F $0 :0!S '  ; !A 'D ( !L &D ;@!E ', ( !.
#[  ]M $\ 5  @ &T 80!T &, : !I &X 9P @ '  80!T '0 90!R &X       , 
#[  ]M 5      #0!H '\ #  0 /__@  F $T 80!T &, :  @ &\ ;@ @ &4 ;@!T
#[  ]M &D <@!E "  ; !I &X 90!S "  ;P!N &P >0       P !4      - '4 
#[  ]M/  , !$ __^  "8 20!G &X ;P!R &4 ( !C &$ <P!E          <  5  
#[  ]M    DP!/ %X -P#_____@ !$ &4 <P!C &4 ;@!D "  1 !I '( 90!C '0 
#[  ]M;P!R &D 90!S       )  -0     )H 6@ \  P #@#__X  )@!! &P =P!A
#[  ]M 'D <P      "0  4     ": &@ /  , !( __^  "8 3@!E '8 90!R    
#[  ]M      D  %      F@!V !4 #  3 /__@  F %0 ;P        "!4     "S
#[  ]M '< $  + !0 __^!             E      QP!X "4 " #_____@@!L &4 
#[  ]6=@!E &P <P @ &\ ;@!L 'D         
#[ ]end
#[]mks internal resource : dialog : DIALOG_2
#[ ]begin : size 242
#[  ]MP #,D      #  8 #P L =(      %4 ; !T '( 80!' '( 90!P "  4@!E
#[  ]M ', =0!L '0 <P    @ 30!3 "  4P!A &X <P @ %, 90!R &D 9@      
#[  ]M 5      ]0"^ #( #@ ! /__@ !# &$ ;@!C &4 ;             %8    
#[  ]M +P O@ R  X 9@#__X  )@!% &0 :0!T "  1@!I &P 90         % (%0
#[  ]M      4 !0 B :\ 90!3 'D <P!, &D <P!T %8 :0!E '< ,P R    1P!E
#[  ]1 &X 90!R &D 8P Q       A
#[ ]end
#[]mks internal resource : icon : \0 : width 32 height 32 colors 16
#[ ]begin : size 744
#[  ]M*    "    !      0 $      "  @                              
#[  ]M (   (    " @ "     @ "  ("   # P,  @("     _P  _P   /__ /\ 
#[  ]M  #_ /\ __\  /___P#_________^O /__O[\   _W]_?W]_<*^@#_\/O[  
#[  ]M /_W]_?W]__Z\ __^_OP  #_?_#P\/#PKZ /_P^_L   __</____"OKP#__[
#[  ]M^_   /]_____\*^OH __#[^P  #_]P___P(B(B /__O[\   _W____ B(B(@
#[  ]M#_\/O[   /_W#_\       __^_OP  #_?__P(/KZ^O#__P^_L   __</ B"O
#[  ]MKZ\/___[^_   /]_\/(@^OKP?W]_#[^P  #P\*^B(*^O!_?W]_O[\   ^OKZ
#[  ]M\B#Z\ \/#P\/O[   *^OKZ(@KP_____P^_OP  #Z^OKR(/#P____#[^_L   
#[  ]M       /?___\/O[^P(        /]_#__P^_O[ B( #_______]___#[^_L*
#[  ]M(B( _______W\/\/O[^PJJHB(/_______W_P^_O["JJJHB+_______?P#[^_
#[  ]ML*JJJJHB#P\/#P\/#_O[^PJJJJJJHK^_O[^_O[^_O[#ZJJJJJJ#[^_O[^_O[
#[  ]M^_L/_ZJJJJH"O[^_O[^_O[^PJO_ZJJJ@HOO[^_O[^_O["JJO_ZJJ"J(     
#[  ]M     *^JJO_ZH*JJ           *^JJO_PJJH            *^JJO#_J@( 
#[  ]M           *^JH*K_ B             *^@JJH/(@   !\    ?    'P  
#[  ]M !\    ?    'P   !\    ?    'P   !\    ?    'P   !\    ?    
#[  ]M'P   !\    /    !P    ,    !                                
#[  ]8     /__  #__X  ___  /__X #___  
#[ ]end
#[]mks internal resource : icon : \1 : width 16 height 16 colors 16
#[ ]begin : size 296
#[  ]M*    !     @     0 $      #                                 
#[  ]M (   (    " @ "     @ "  ("   # P,  @("     _P  _P   /__ /\ 
#[  ]M  #_ /\ __\  /___P#_B(B(H/B_ /^/_XJ@^/L _X_X(B#XOP#_CX   /C[
#[  ]M /^("JH/^+\ B((*H/_X^P"JH@H(B(B_ *JB (__B_L    /C_B_L"#___^/
#[  ]MB_L*(O___XB_L*HBB(B(B_L*JJ*_O[^_L/JJH/O[^_L*KZH*     "JJ\*( 
#[  ]M     JH/H@ #6 4  P#_  /_^P #_P   P    ,'_P #__\  P("  $" @  
#[  ]: /\   #_  #[         /\'_P#___^   +P
#[ ]end