' ********************************************************************
' 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
'
' Adapted for BaCon 3.0 and higher at April 22, 2014 - PvE.
' ********************************************************************


' *********************
' 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,i 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
' *********************