3

[ Skill ] load 函数优化,识别相对路径 - YEUNGCHIE

 2 years ago
source link: https://www.cnblogs.com/yeungchie/p/15999427.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

[ Skill ] load 函数优化,识别相对路径

https://www.cnblogs.com/yeungchie/

cds.lib 文件中定义库的路径,为了规范库定义的管理,经常这样做:

.
|-- cds.lib ------------------- cat --> 1| INCLUDE ./common/cds.lib
`-- common
    |-- cds.lib --------------- cat --> 1| INCLUDE ./project/cds.lib
    |                                   2| INCLUDE ./project/cds.lib
    |-- project
    |   |-- cds.lib ----------- cat --> 1| INCLUDE ./layout/cds.lib
    |   |                               2| INCLUDE ./sch/cds.lib
    |   |                               3| 略 ...
    |   |-- layout
    |   |   `-- cds.lib ------- cat --> 1| DEFINE layout_lib1 ./layout_lib1
    |   |                               2| DEFINE layout_lib2 ./layout_lib2
    |   |                               3| 略略 ...
    |   |-- sch
    |   |   `-- cds.lib ------- cat --> 1| 略略略 ...
    |   `-- 略略略略 ...
    `-- 略略略略略 ...

可以看到,对于 cds.lib 文件来说,INCLDUE / DEFINE 都可以使用相对路径。
而在 Skill 中使用 load() / loadi() 函数却不能支持相对路径:

*Error* load: can't access file - "./dir/test.il"
*Error* load: error while loading file - "/home/yeung/tmp/load.il" at line 1

在上一篇随笔 文件读写 & IO 句柄 整理的内容中,发现内置的句柄 piport 可以获取当前文件的路径这一特性,于是有了这一篇。

__FILE__

在 Perl 中 __FILE__ 用来获取当前文件的路径,这里模仿一个。

procedure(__FILE__()
    get_filename(piport)
); __FILE__
  • printf("Current path: %s\n" (__FILE__))
    ; Current path: /home/yeung/tmp/load.il
    

__DIR__

正则处理,从 __FILE__ 函数结果中提取父目录的路径。
需要注意的是,如果是在 CIW 中执行 __FILE__ 函数,它的返回值会是 *ciwInPort*,这种情况直接用 getWorkingDir() 作为 __DIR__ 函数的返回值。

procedure(__DIR__(\@optional path((__FILE__)) "t")
    if(pcreMatchp("^\\*.+\\*$" path)
        getWorkingDir()
        pcreReplace(pcreCompile("(?<=/)[^/]+/*$") path "" 0)
    )
); __DIR__
  • printf("Current directory: %s\n" (__DIR__))
    ; Current directory: /home/yeung/tmp/
    

ycReadRelPath

这个函数用来将 相对路径 转为 绝对路径
当输入路径 path 为 ~ 或者 / 开头时,说明已经是绝对路径了,这种情况直接原封不动返回。

procedure(ycReadRelPath(\@optional file("") "t")
    let((path)
        path = if(pcreMatchp("^[~/]" file)
            file
            sprintf(nil "%s/%s" (__DIR__) file)
        )
        simplifyFilename(path t)
    ); let
); ycReadRelPath
  • printf("Target path: %s\n" ycReadRelPath("./init/load.il"))
    ; Target path: /home/yeung/tmp/dir/test.il
    

ycLoad

优化 load 函数。
预留一个 ignores 参数用来优化 loadi 函数。

procedure(ycLoad(file \@optional ignore "tg")
    let((path)
        path = ycReadRelPath(file)
        unless(isFile(path)
            error("ycLoad: not a valid file - %A" path)
        )
        unless(isReadable(path)
            error("ycLoad: can't access file - %A" path)
        )
        if(ignore loadi(path) load(path))
    )
); ycLoad

ycLoadi

优化 loadi 函数。
同样可以忽略 load 过程中遇到的错误,打印错误消息,然后继续 load 。

procedure(ycLoadi(file "t")
    ycLoad(file t)
); ycLoadi
  • 以前 load

    let((home wind sync)
        home = "/home/yeung/script/skill/tools/"
        wind = list("hiForm.il" "windCtrl.il")
        sync = list("syncView.il" "support3rd.il")
        foreach(x wind
            load(strcat(home "src/wind/" x))
        )
        foreach(x sync
            load(strcat(home "/src/sync/" x))
        )
    ); let
    

    非常啰嗦。
    其次如果父文件夹改了名,或者移动了位置,还得一个个文件打开检查路径并修改,还要增加无意义的版本。
    copy 给别人也不能傻瓜式操作,直接 load 报个错:

    *Error* load: can't access
    " 唉 你 这 脚 本 有 问 题 啊 ? "
  • 现在 load

    ycLoad("src/wind/hiForm.il")
    ycLoad("src/wind/windCtrl.il")
    ycLoad("src/sync/syncView.il")
    ycLoad("src/sync/support3rd.il")
    

    "优雅地" load 完所有文件。

    doge_add_one.png

继续优化可以再识别 Shell 环境中的变量。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK