' ********************************************************************
' PROGRAM:      bwhich.bac (a BaCon-enhanced which)
' PURPOSE:      a somewhat fuzzy, which-like command allowing for
'                       partial and multiple keyword specification in
'                       searches of dirs contained in the $PATH variable
' AUTHOR:               vovchik (Puppy Linux forum)             
' DEPENDS:      gcc, bacon, sort
' PLATFORM:     Puppy Linux (actually, any *nix)
' DATE:         13-06-2011
' NOTE:         I got the idea from Akkana Peck's useful python
'                       script 'pathmatch' but didn't really want to port
'                       any of the python code contained therein (writing
'                       afresh is often faster/easier)
' LICENSE:      you may use or modify this program to you heart's
'                       content under the terms of the GPL
' ********************************************************************


' *********************
' DECLARATIONS
' *********************

OPTION COLLAPSE 1
DECLARE myfiles$, argstring$ TYPE STRING
DECLARE terse TYPE NUMBER
DECLARE version$ = "0.1a"

' *********************
' END DECLARATIONS
' *********************


' *********************
' SUBS & FUNCTIONS
' *********************

' -----------------
SUB USAGE(STRING thisapp$)
' -----------------
        thisapp$ = MID$(thisapp$, INSTRREV(thisapp$, "/") + 1)
        PRINT "Usage:    ", thisapp$, " [-t] keyword1 keyword2 ...."
        PRINT "          (shows all executables in your $PATH that contain keyword[s])"
        PRINT "          -t means terse (shows only names of executables without full path)"
        PRINT "          -h shows this help"
        PRINT "          NB. The ", thisapp$, " keyword[s] search is case insensitive."
        PRINT "Example:  ", thisapp$, " pic img"
        PRINT "Result:   /root/my-applications/bin/pshowpic"
        PRINT "          /usr/bin/gpic"
        PRINT "          /usr/bin/gpick"
        PRINT "          /usr/bin/imgcmp"
        PRINT "          /usr/bin/imginfo"
        PRINT "          /usr/bin/pic"
        PRINT "          /usr/bin/pic2graph"
        PRINT "          /usr/bin/piconv"
        PRINT "          /usr/bin/vapicheck"
        PRINT "          /usr/local/bin/picpuz"
        PRINT "          /usr/local/bin/picscale"
        PRINT "          /usr/local/bin/Pictureviewer"
        PRINT "Author:   vovchik, June 2011, Puppy Linux Forum (murga-linux.com/puppy)"
        PRINT "License:  GPL"
        PRINT "Version:  ", version$, " (check out BaCon at www.basic-converter.org)"
        END
END SUB

' -----------------
SUB GET_ARGS()
' -----------------
        LOCAL myarg$ TYPE STRING
        LOCAL arg1 TYPE NUMBER
        terse = 0
        myarg$ = REPLACE$(ARGUMENT$, "*", "")
        SPLIT myarg$ BY " " TO argv$ SIZE argc
        IF argc > 1 THEN
                IF INSTR(argv$[1], "-h") OR argc < 2 THEN
                        CALL USAGE(argv$[0])
                ELIF INSTR(argv$[1], "-t") AND argc < 3 THEN
                        CALL USAGE(argv$[0])
                ELIF argv$[1] = "-t" AND argc > 2 THEN
                        terse = 1
                        arg1 = 2
                ELSE
                        arg1 = 1
                END IF
        ELSE
                CALL USAGE(argv$[0])
        END IF
        FOR i = arg1 TO argc - 1
                argstring$ = CONCAT$(argstring$, argv$[i], " ")
        NEXT i
END SUB

' -----------------
SUB SEARCH_DIRS()
' -----------------
        LOCAL myfile$, mypath$, myprog$ TYPE STRING
        LOCAL i, j TYPE NUMBER
        myfile$ = ""
        myfiles$ = ""
        mypath$ = CHOP$(GETENVIRON$("PATH"))
        SPLIT mypath$ BY ":" TO pathdirs$ SIZE pathcount
        SPLIT argstring$ BY " " TO argstrings$ SIZE myargs
        FOR i = 0 TO pathcount - 1
                IF RIGHT$(pathdirs$[i],1) = "/" THEN
                        pathdirs$[i] = LEFT$(pathdirs$[i], LEN(pathdirs$[i]) - 1)
                END IF
                IF FILETYPE(pathdirs$[i]) = 2 THEN
                        OPEN pathdirs$[i] FOR DIRECTORY AS mydir
                        REPEAT
                                GETFILE myfile$ FROM mydir
                                FOR j = 0 TO myargs - 1
                                        myprog$ = MID$(myfile$, INSTRREV(myfile$, "/") + 1)
                                        IF INSTR(LCASE$(myprog$), LCASE$(argstrings$[j])) THEN
                                                myfiles$ = CONCAT$(myfiles$, pathdirs$[i], "/", myfile$, NL$)
                                        END IF
                                NEXT j
                        UNTIL ISFALSE(LEN(myfile$))
                        CLOSE DIRECTORY mydir
                END IF
        NEXT i
END SUB

' -----------------
SUB SHOW_RESULTS()
' ----------------- 
        LOCAL i TYPE NUMBER
        myfiles$ = CHOP$(EXEC$(CONCAT$("echo ", CHR$(34),myfiles$, CHR$(34)," | sort -u")))
        IF terse THEN
                SPLIT myfiles$ BY NL$ TO mylist$ SIZE mylistcount
                FOR i = 0 TO mylistcount - 1
                        PRINT MID$(mylist$[i], INSTRREV(mylist$[i], "/") + 1)
                NEXT i
        ELSE
                PRINT myfiles$
        END IF
END SUB

' *********************
' END SUBS & FUNCTIONS
' *********************


' *********************
' MAIN
' *********************

GET_ARGS
SEARCH_DIRS
SHOW_RESULTS
END

' *********************
' END MAIN
' *********************