# split_path

Definition: | sequence res = split_path(string path, bool preservetrailsep=false)
Description: | The logical counterpart to join_path(), split_path() breaks up a path into a sequence of path fragments. Returns a sequence of sub-strings of path.
pwa/p2js: | Supported. Not that it’s very likely to be useful, but it is just string manipulation, so there’s little point in deliberately disabling it.
Comments: | Paths are split on either Windows ('\\') or Linux ('/') separators. A leading separator is always preserved, and any consecutive ones are skippped. Note that any preserved cross-platform path separators may cause issues, see technicalia.
Example 1: |
    ?split_path(`C:\Program Files (x86)\Phix\demo\edix`)
            -- {`C:`,`Program Files (x86)`,`Phix`,`demo`,`edix`}
    ?split_path(`demo\edix`)                            -- {`demo`,`edix`}
    ?split_path(`\demo\edix`)                           -- {`\demo`,`edix`}
    ?split_path(`usr/home/john`)                        -- {`usr`,`home`,`john`}
    ?split_path(`/usr/home/john`)                       -- {`/usr`,`home`,`john`}
    ?split_path(`demo\edix\`)                           -- {`demo`,`edix`}
    ?split_path(`demo\edix\`,preservetrailsep:=true)    -- {`demo`,`edix\`}
    ?split_path(`demo\edix`,preservetrailsep:=true)     -- {`demo`,`edix`}
    ?split_path(`demo/edix/`)                           -- {`demo`,`edix`}
    ?split_path(`demo/edix/`,preservetrailsep:=true)    -- {`demo`,`edix/`}
    ?split_path(``)                                     -- {}
The use of a named parameter for preservetrailsep makes the intent much clearer.
Implementation: | See builtins\psplit.e (an autoinclude) for details of the actual implementation.
See Also: | join_path
Technicalia | It may be that many programs, in which the following kind of path separator confusion occurs internally, actually work perfectly fine anyway - but there is certainly no guarantee of that. Note that join_path automatically uses the appropriate platform-specific separator, however should split_path preserve any leading/trailing separators, it will do so without substituting them for the correct platform-specific one, which as shown in this second example may cause mishaps (as marked with (*)). Should this occur, my recommendation would be to use substitute() on path before passing it to split_path(), as shown in the third example, or better yet (as long as you do not mind that any relative paths are replaced with fully qualified ones) get_proper_path(). UPDATE: two of the original errors have now been fixed, but one more new one has been found (though my attitude remains that you would be far better off properly testing an application on different platforms, rather than complaining that this routine occasionally does daft things if you ask it to, such as use /home on Windows or C:\\ on Linux). Example 2:
    ?join_path(split_path(`C:\Program Files (x86)\Phix\demo\edix`))
            -- `C:\Program Files (x86)\Phix\demo\edix` (on Windows)
    ?join_path(split_path(`demo\edix`))         -- `demo\edix`  (on Windows)
    ?join_path(split_path(`\demo\edix`))        -- `\demo\edix` (on Windows)
    ?join_path(split_path(`\demo\edix`))        -- `\demo/edix` (on Linux (*))
    ?join_path(split_path(`home/john`))         -- `home\john`  (on Windows)
    ?join_path(split_path(`/home/john`))        -- `/home/john` (on Linux)
    ?join_path(split_path(`/home/john`))        -- `/home\john` (on Windows (*))
    ?join_path(split_path(`demo\edix\`),1)      -- `demo\edix\` (on Windows)
    ?join_path(split_path(`demo/edix/`,1),1)    -- `demo\edix\` (on Windows) [now fixed]
    ?join_path(split_path(`demo/edix/`),1)      -- `demo/edix/` (on Linux)
    ?join_path(split_path(`demo\edix\`,1),1)    -- `demo/edix/` (on Linux) [now fixed]
    ?join_path(split_path(``))                  -- ``
It is of course join_path(), rather than split_path(), that is giving us the platform-specific results here. Example 3:
    string {sep1,sep2} = iff(platform()=WINDOWS?{`/`,`\`}:{`\`,`/`}),
           path = substitute(`demo/edix/`,sep1,sep2)
    --or
    --string path = get_proper_path(`demo/edix/`,1)
    -- (path may be `C:\Program Files (x86)\Phix\demo\edix\`)
    ?join_path(split_path(path,1))      -- `/demo/edix` (on Linux)
    ?join_path(split_path(path,1),1)    -- `demo\edix\` (on Windows)
    ?join_path(split_path(path,1),1)    -- `demo/edix/` (on Linux)
I should also note that there is no direct correlation between the preservetrailsep parameter of split_path and the trailsep argument of join_path - sometimes both may be needed, sometimes one but not the other, sometimes the other way round, and sometimes neither.