For what it's worth ...
Edit: Modified to accept a single string (a folder name) or a list of strings (folder names, each successively nested).
;;=====================================================================
;;
;; LoadSupport.lsp © 2005-2006 Michael Puckett. All Rights Reserved.
;;
;;---------------------------------------------------------------------
;;
;; In short, <safe> load each LISP (lsp|fas|vlx) file found in a flat
;; or succesively nested folder branch.
;;
;;=====================================================================
(defun LoadSupport
;;=================================================================
;;
;; Typical folder structures and function calls
;;
;;-----------------------------------------------------------------
;;
;; NESTED FOLDER STRUCTURES
;;
;; For a huge operation that is split over multiple cities and
;; multiple disciplines, each with specilized requirements, the
;; LISP files might be distributed in a hiearchy like this --
;;
;; k:\CAD\LISP\Common ;; Company's main LISP library
;; | ;;
;; +-- Calgary ;; LISP specific to Calgary
;; | | ;;
;; | +-- Civil ;; LISP specific to Civil
;; | | ;;
;; | +-- Elec ;; LISP specific to Elec
;; | | ;;
;; | +-- Piping ;; LISP specific to Piping
;; | ;;
;; +-- Toronto ;; LISP specific to Toronto
;; | | ;;
;; | +-- Civil ;; LISP specific to Civil
;; | | ;;
;; | +-- Elec ;; LISP specific to Elec
;; | | ;;
;; | +-- Piping ;; LISP specific to Piping
;; | ;;
;; +-- Vancouver ;; LISP specific to Vancouver
;; | ;;
;; +-- Civil ;; LISP specific to Civil
;; | ;;
;; +-- Elec ;; LISP specific to Elec
;; | ;;
;; +-- Piping ;; LISP specific to Piping
;;
;; Corresponding function call for a Calgary PC, Electrical
;; discipline --
;;
;; (LoadSupport filename
;; '(
;; "K:\\CAD\\LISP\\Common"
;; "Calgary"
;; "Elec"
;; )
;; )
;;
;; Loading K:\CAD\LISP\Common ...
;;
;; common1.lsp ... loaded
;; common2.lsp ... loaded
;; common3.lsp ... loaded
;;
;; Loading K:\CAD\LISP\Common\Calgary ...
;;
;; Calgary.lsp ... loaded
;;
;; Loading K:\CAD\LISP\Common\Calgary\Elec ...
;;
;; grounding.lsp ... loaded
;; raceway.lsp ... loaded
;;
;; Please note that the function is not hard coded to a specific
;; number of nested folders. Maybe you decide this suits you
;; better --
;;
;; k:\CAD\LISP\Common ;; common support lisp
;; | ;;
;; +-- Civil ;; lisp specific to Civil
;; | ;;
;; +-- Elec ;; lisp specific to Elec
;; | ;;
;; +-- Piping ;; lisp specific to Piping
;;
;; Corresponding function call for a Piper's CADD Machine --
;;
;; (LoadSupport filename
;; '(
;; "K:\\CAD\\LISP\\Common"
;; "Piping"
;; )
;; )
;;
;; Loading K:\CAD\LISP\Common ...
;;
;; common1.lsp ... loaded
;; common2.lsp ... loaded
;; common3.lsp ... loaded
;;
;; Loading K:\CAD\LISP\Common\Piping ...
;;
;; isogen.lsp ... loaded
;; routing.lsp ... loaded
;;
;; Note that each tier in the folder structure may | may not have
;; LISP files. That is, it is not mandatory for each tier to have
;; LISP files. The program will report what files are loaded as
;; they are loaded.
;;
;; Also, this means you can have other related files reside in each
;; tier, perhaps text files that host info related to the files
;; but not appropriate to reside in the actual LISP source code.
;;
;; Or maybe you have nothing but compiled vlx files in the
;; structure with some accompanying text files, keeping the
;; original source code safe in another location.
;;
;; Because each successive folder depth represents increased
;; specalization, said folders tend to contain less and less. To
;; me, drilling down thru a directory structure to find and edit
;; a LISP file is faster and more organized than piling hundreds
;; of LISP files into one flat directory structure, the impetus
;; for authoring this beast.
;;
;; FLAT FOLDER STRUCTURE.
;;
;; Maybe you decide, meh, all this nested folder nonesence is
;; well, just overkill, but you like the idea of having a function
;; that will load all LISP files in a specific folder. Simple --
;;
;; (LoadSupport "K:\\CAD\\LISP\\Common")
;;
;; Loading K:\CAD\LISP\Common ...
;;
;; common1.lsp ... loaded
;; common2.lsp ... loaded
;; common3.lsp ... loaded
;;
;; The function has been coded to accept a single string (a folder
;; name) or a list of folders, each successivly nested (as
;; previously mentioned).
;;
;; ERROR HANDLING
;;
;; The actual LISP loader is error trapped, so if an error is
;; encountered during the loading of a LISP file it will attempt
;; to report the loading error AND then continue loading the
;; balance of the files. For example --
;;
;; (loadsupport
;; '(
;; "K:\\CAD\\LISP\\Common"
;; "Calgary"
;; "Elec"
;; )
;; )
;;
;; Loading K:\CAD\LISP\Common ...
;;
;; common1.lsp ... loaded
;; common2.lsp ... failed <divide by zero>
;; common3.lsp ... loaded
;;
;; Loading K:\CAD\LISP\Common\Calgary ...
;;
;; Calgary.lsp ... loaded
;;
;; Loading K:\CAD\LISP\Common\Calgary\Elec ...
;;
;; grounding.lsp ... loaded
;; raceway.lsp ... loaded
;;
;; OTHER MINUTIA / NOTES / SEWERAGE
;;
;; At this point you may be thinking, why not just use a recursive
;; function that loads every LISP file found in a directory tree?
;; Well thats not what I want, even though that's easier to code.
;;
;; Allow me to illuminate. I want to load all LISP files in a
;; specific branch of a directory structure --
;;
;; Only
;;
;; K:\CAD\LISP\Common\ *.lsp|fas|vlx
;; K:\CAD\LISP\Common\Calgary\ *.lsp|fas|vlx
;; K:\CAD\LISP\Common\Calgary\Elec\ *.lsp|fas|vlx
;;
;; NOT
;;
;; K:\CAD\LISP\Common\ *.lsp|fas|vlx
;; K:\CAD\LISP\Common\Calgary\ *.lsp|fas|vlx
;; K:\CAD\LISP\Common\Calgary\Elec\ *.lsp|fas|vlx
;; K:\CAD\LISP\Common\Calgary\Civil\ *.lsp|fas|vlx
;; K:\CAD\LISP\Common\Calgary\Piping\ *.lsp|fas|vlx
;; K:\CAD\LISP\Common\Toronto\ *.lsp|fas|vlx
;; K:\CAD\LISP\Common\Toronto\Elec\ *.lsp|fas|vlx
;; K:\CAD\LISP\Common\Toronto\Civil\ *.lsp|fas|vlx
;; K:\CAD\LISP\Common\Toronto\Piping\ *.lsp|fas|vlx
;; ...
;;
;; Ahh you say, why not recursively load starting at the deepest
;; node working your way all the way to the parent? The problem
;; with that approach is that the parent is likely not what I
;; consider the parent. For example, using the sample data above
;; the recursively determined parent would be K:\ or perhaps
;; K:\CAD, whereas in reality I don't wish to load any files above
;; the K:\CAD\COMMON folder.
;;
;;-----------------------------------------------------------------
;;
;; Yeah, I don't sleep much.
;;
;;=================================================================
(
folderlist
/
_StripPath
_GetLispFiles
_SafeLoad
_LoadFolder
_LoadFolders
_Main
)
;;=================================================================
;;
;; (_StripPath filename)
;;
;;-----------------------------------------------------------------
;;
;; strip the path from a filename,
;;
;; e.g c:\folder\filename.lsp => filename.lsp
;;
;;=================================================================
(defun _StripPath ( filename )
(strcat
(vl-filename-base filename)
(vl-filename-extension filename)
)
)
;;=================================================================
;;
;; (_GetLispFiles path)
;;
;;-----------------------------------------------------------------
;;
;; get all lsp/fas/vlx files for path, return sorted by group
;;
;;=================================================================
(defun _GetLispFiles ( path / result )
(apply 'append
(mapcar
'(lambda (filter)
(vl-sort
(vl-directory-files
path
filter
1
)
'<
)
)
'("*.lsp" "*.fas" "*.vlx")
)
)
)
;;=================================================================
;;
;; (_SafeLoad filename)
;;
;;-----------------------------------------------------------------
;;
;; safely load a lsp/fas/vlx etc. Print any error message
;; generated if the load is unsuccessful and an associated error
;; msg captured
;;
;;=================================================================
(defun _SafeLoad ( filename / filepath failed loaded error )
(cond
( (setq filepath (findfile filename))
(princ
(strcat
"\t\t"
(_StripPath filePath)
" ... "
)
)
(setq error
(vl-catch-all-apply
'(lambda ( )
(load filepath)
(setq loaded
(null failed)
)
)
)
)
(princ
(strcat
(if loaded
"loaded"
(strcat
"failed"
(if (vl-catch-all-error-p error)
(strcat
" <"
(vl-catch-all-error-message error)
">"
)
" <no error description>"
)
)
)
"\n"
)
)
loaded
)
( (princ
(strcat
"\t\t"
"File <"
filename
"> not found.\n"
)
)
nil
)
)
)
;;=================================================================
;;
;; (_LoadFolder folder)
;;
;;-----------------------------------------------------------------
;;
;; safely load all lisp / fas / vlx files found in path
;;
;;=================================================================
(defun _LoadFolder ( folder / lispFiles )
(cond
( (vl-file-directory-p folder)
(princ
(strcat
"\nLoading "
folder
" ...\n\n"
)
)
(foreach lispFile
(setq lispFiles (_GetLispFiles folder))
(_SafeLoad (strcat folder "\\" lispFile))
)
(if (null lispFiles)
(princ "\t\t<none found>\n")
)
)
(
(princ
(strcat
"\nInvalid path <"
folder
"> ignored ...\n\n"
)
)
)
)
)
;;=================================================================
;;
;; (_LoadFolders '("K:\\CAD\\LISP" "Calgary" "Elec" ... ))
;;
;;-----------------------------------------------------------------
;;
;; Try to load a tree of support files, where each node (folder)
;; is a child of the preceeding folder and may or may not have
;; lisp files (*.lsp|fas|vlx) and / or child folders.
;;
;; K:\\CAD\\LISP\ ;; *.lsp|fas|vlx
;; ;;
;; K:\\CAD\\LISP\Calgary\ ;; *.lsp|fas|vlx
;; ;;
;; K:\\CAD\\LISP\Calgary\Elec ;; *.lsp|fas|vlx
;;
;; ...
;;
;;=================================================================
(defun _LoadFolders ( folderList / currentFolder )
(foreach folder folderList
(if (eq 'str (type folder))
(_LoadFolder
(setq currentFolder
(if currentFolder
(strcat currentFolder "\\" folder)
folder
)
)
)
)
)
)
;;=================================================================
;;
;; (_Main folderList )
;;
;;-----------------------------------------------------------------
;;
;; wrap all functionality defined herein, ergo: 'the solution'
;;
;;=================================================================
(defun _Main ( folderList )
(_LoadFolders folderList)
(princ)
)
;;=================================================================
;;
;; helper functions defined, party on dude -> invoke _Main
;;
;;-----------------------------------------------------------------
;;
;; (Pre) handle a single string (a folder name) or a list of
;; strings (folder names, each successively nested).
;;
;;=================================================================
(_Main
(cond
( (listp folderList)
folderList
)
( (eq 'str (type folderList))
(list folderList)
)
( (princ
(strcat
"Error. Invalid input: (LoadSupport "
(vl-princ-to-string folderList)
").\n"
"Syntax: (LoadSupport \"x:\\Path\") or "
"(LoadSupport '(\"x:\\Path\" \"subfolder\"))"
)
)
nil
)
)
)
)
;;=====================================================================
;;
;; end LoadSupport.lsp
;;
;;=====================================================================
:ugly: