内部函数转普通函数的最简代码及深度挖掘
本帖最后由 highflybird 于 2022-8-31 12:54 编辑近来大家对内部函数的热度一直不减,但是目前的方法,不管是老猫,还是tryhi网友的方法,似乎有个缺陷,如果要转换一个函数需要临时生成fas文件,有点不便,且可能会CAD弹框。
最近在网友baitang36的大力帮助下,完成了一个最新的转换法--利用tranf函数进行转化。
加载本帖的附件后,就能利用TRANF函数把系统内部函数转为普通函数,且不再生成中间文件,再利用al-add-subr-name(晨语发现)就可以加载到全局,即每个打开的文档都能用,并受到函数保护。
TRANF用法举例:
(tranf "al-add-subr-name") ==>T
(tranf 'al-add-subr-name) ==>T
al-add-subr-name用法:
(al-add-subr-name '内部函数名)
或者(al-add-subr-name '("新函数名" . 内部函数名))
例如:
_$ (al-add-subr-name 'itoa)
ITOA
_$ (al-add-subr-name '("hfb-itoa" . itoa))
("hfb-itoa" . ITOA)
_$ hfb-itoa
#<SUBR @14e5d384 hfb-itoa>
说明:在2021及更高版本,需要设置lispsys为0,并重启CAD。
还是和以前一样,隐藏函数要隐藏起来!
附件如下:
**** Hidden Message *****
再次感谢各位网友!
最后要说明的是,这个中间生成的fas尽量做到了最小,在baitang36的调整下,只有139个字节大小。基本上再没有多余的字节。
另外,在LISP代码上写得尽量简短。 当然,肯定不是最简的。大家还可以继续优化。
最新:根据baitang36大神的fas,更新了LISP附件,再次致谢!
20220823.更新,在不死猫的帮助下,再次刷新了fas文件大小,并修改了几个bug。致谢老猫!
20220824.得到了一个更简的办法,在此处留给大家猜谜。
20220831.针对一些高版本加载错误,或者不想修改lispsys的,发布新的版本v1.1,详见附件。
有了这个程序,我们现在就可以知道CAD究竟藏了多少秘密。
就在这几天的深度挖掘过程中,发现了一个有意思的内部函数,并通过这个内部函数来寻找CAD的隐藏函数及符号。
老猫他们找到了一万多个,我用了一小段代码,一秒钟不到就得到了两万多个可用的lisp内部和普通函数及符号,而总数达三万多个。
这个数字可能要依据各人电脑和版本的情况有所变化。
那么你问我是怎么得到的呢?
第二部分隐藏内容来了:不要套娃啊~~~~!
**** Hidden Message *****
顺便我从得到的函数中发现了一个从来没见过的CAD命令:acadinfo.
大家试试输入看看,是不是很丰富哦!
PS:在只加载了ET工具的AutoCAD2006上和AutoCAD2023上做了测试,对得到的函数进行了消重和排序处理,现在结果看起来好多了。
不过发现数量一下子少多了,估计autolisp和lpp有很多重名的。
2006:内部数量:5858,普通数量:3665。
2023:内部数量:5874,普通数量:4394。 本帖最后由 自贡黄明儒 于 2022-9-17 14:13 编辑
今天试了几个函数
;;[功能]去掉之字符串小数点后字符
命令: (tranf 'filename-non-extension)
T
命令: (filename-non-extension "D:\\1.txt")
"D:\\1"
命令: (filename-non-extension "D:\\1.txt.txt")
"D:\\1.txt"
;;[功能]文件名分成三部分
(tranf 'as:fnsplitl)
(as:fnsplitl "D:\\0000\\1.txt");==>("D:\\0000\\" "1" ".txt")
(fnsplitl "D:\\0000\\1.txt.txt");==>("D:\\0000\\" "1.txt" ".txt")
;;参考as:fnsplitl
;;[功能]lisp编辑器无法再编辑??
(tranf 'sys-top);==>T
(sys-top)
;;[功能]盘符序列号
(tranf 'FIND_SERIALNUMBER);;==>T
(FIND_SERIALNUMBER "c:")
(FIND_SERIALNUMBER "D:\\")
;get-logical-drives
;;[功能]盘符
(tranf "get-logical-drives")
(get-logical-drives)
(tranf "_read-nb")
(tranf "_write-nb-str")
;;;(setq fname (findfile "D:\\0000\\1.lsp"))
;;;(setq f (open fname "r"))
;;;(setq str (_read-nb 64000000 f))
;;;(close f)
;;[功能]文件大小(多少字节),同vl-file-size
(tranf "file-size")
(file-size "D:\\0000\\1.txt")
(tranf "file-mod-time")
(tranf "file-read-only-p")
(tranf "file-readable-p")
(file-mod-time "D:\\0000\\1.txt");不知这个时间怎么搞
(file-read-only-p "D:\\0000\\1.txt");只读为T
(file-readable-p "D:\\0000\\1.txt");可读
(tranf "member-if")
(tranf "member-if-not")
(member-if 'numberp '("a" 1 "a" 1))
(member-if 'numberp '("a" "a" 1 "a" 1));==>(1 "a" 1)
(tranf "merge")
(merge '(1 2) '(4 5) +);==>(4 5 1 2)
(merge '((1) 2) '((3)(3)) 'append);==>((3) (3) (1) 2)
;;(if (member item list) list (cons item list))
(tranf "adjoin")
(adjoin 2 '(3 5));==>(2 3 5)
(adjoin 2 '(3 5 2));==>(3 5 2)
;;不好用,只能三个参数,最后一个须是表
(tranf "acons")
(acons 1 2 '(3));==>((1 . 2) 3)
(tranf "butlast")
(butlast '(1 2 3 4));==>(1 2 3)
;;类似VBS中的写法了
(tranf "funcall")
(funcall '+ 1 2 3)
(funcall + 1 2 3);==>6
(tranf "reduce")
(reduce '+ '(1 2 3) 4);==>10
(tranf "make-list")
(make-list 5 4);==>(4 4 4 4 4)
(make-list 5);==>(nil nil nil nil nil)
;;相当于append
(tranf "nconc")
(nconc '(1 2) '(2) 3);==>(1 2 2 . 3)前面必须是表
(nconc '(1 2) '(2) '(3 4));>>(1 2 2 3 4)
(nconc '(1 2) '(1 2));(1 2 1 2)
;;只能两个参数表;前面一个表倒置了
(tranf "nreconc")
(nreconc '(1 2) '(3 4));==>(2 1 3 4)
(nreconc '(1 2) 3);==>(2 1 . 3)
;;只能是点对中搜索,按后一个元素搜索
(tranf "rassoc")
(rassoc 'a '((a . b) (b . c) (c . a) (z . a)));==>(C . A)按后一个元素搜索
(rassoc 3 '((1 . 2) (3 . 2) (4 . 3) (5 . 3)));(4 . 3)
(assoc 3 '((1 2) (3 2) (4 3) (5 3)));==>(3 2)这个可以是表
;;换第一个元素
(tranf "rplaca")
(rplaca '(1 2 3 4) 5);==>(5 2 3 4)
;;(cons (car x) lst)
(tranf "rplacd")
(rplacd '(3 2 3 4) 5);==>(3 . 5)取第一个元素组成点对
(rplacd '(3 2 3 4) '(5 0 1));(3 5 0 1)
(tranf "string->list")
(string->list "A自");(65 215 212)同(VL-STRING->LIST "A自") "12自贡3"
(tranf "string-append")
(string-append "A自" "3" "3");"A自33",相当于strcat
(tranf "string-by-char-to-list")
(string-by-char-to-list "AAb3b3自" (ascii "b"));("AA" "3" "3自")
;;不支持中文
(string-by-char-to-list "AAb自3b自3自" (ascii "自"));("AAb" "?b" "?" "
;;首字母大写
(tranf "string-capitalize")
(string-capitalize "hello,world");"Hello,World"
(string-capitalize "hello,world")
;;大写(不如strcase好用)
(tranf "string-upcase")
(string-upcase "hello,world自");"HELLO,WORLD自"
(strcase "hEllo,world自" t);"hello,world自"
;;计数
(tranf "string-count")
(string-count (ascii "b") "自ababc");2 "b"的数量
(tranf "string-downcase")
(string-downcase "Hello,World");"hello,world"
;;(VL-STRING->LIST "Hello,World");(72 101 108 108 111 44 87 111 114 108 100)
(tranf "string-elt");字符串中的位移。第一个字符的位移为 0
(string-elt "Hello,World" 2);108
(tranf "string-elt<-")
(setq a "hello")
(string-elt<- a 65 2);此时a 变成了"heAlo"
;;猜不出
(tranf "string-expand-clip")
(string-expand-clip "Hello,World")
;;是否有前缀
(tranf "string-has-prefix-p")
(string-has-prefix-p "hello" "he");T 区分大小写
(tranf "string-left-trim")
(string-left-trim "he" "hello");"llo" 同VL-STRING-LEFT-TRIM
;;字符串长度
(tranf "string-length")
(string-length "hello");5
(string-length "hello自");7 看来中文还是按2个长度计算的。
(strlength "hello自")
;;不好猜
(tranf "string<")
(string< "Atxt" "bbb");t
(string< "aaaaaaa" "bb" "bbb");t
;;是否字符串
(tranf "stringp")
(stringp "2Atxt");t
(stringp 2);nil
(stringp (car(entsel)));nil
;;字符串是否相同
(tranf "string=")
(string= "2Atxt" "2Atxt" "2Atxt");t
(string= "ABC" "abc");nil 区分大小写
;;[功能]只能比较字符串,不区分大小写
(tranf "string-equal")
(string-equal ".Fas" ".fas" ".fAs");===>T
(string-equal ".fas" "a.Fas");===>nil
;;前后剪切
(tranf "string-trim")
(string-trim" .F" " .Fa sF ");" .Fas " 同VL-STRING-TRIM
(VL-STRING-TRIM" .F" " .Fa sF ")
(tranf "string-right-trim")
;;字符串填充
(tranf "string-fill")
(setq a "abc")
(string-fill a 65);!a==>"AAA"
;;(chr 65)==>"A"
;;string-key-value
;;string-lessp
;;string-mismatch
;;string-position
;;string-psubst
;;string-resource
;;string-search
;;string-subseq
;;string-subst
;;string-translate
换了一个写法,101字节,如果不在乎返回值还能再精简点。
字节码:
(13 70 65 83 52 45 70 73 76 69 32 59 13 49 13 49 32 36 1 36 13 55 51 32 49 32 36 20 1 1 1 0 91 116 114 97 110 102 0 255 0 0 57 1 0 86 108 112 112 45 115 121 109 102 117 110 45 62 97 108 0 105 110 116 101 114 110 0 0 91 255 0 0 86 58 76 80 80 0 0 57 3 0 57 2 0 57 2 0 91 115 101 116 0 0 52 2 3 2 22 36)
本帖最后由 baitang36 于 2022-8-22 12:30 编辑
目前的最短记录是86个字节,看谁能更短一些?
Offset 01234567 89 10 11 12 13 14 15
00000000 46 41 53 34 2D 46 49 4C45 0A 31 0A 30 20 24 20 FAS4-FILE 1 0 $
00000016 24 0A 36 31 20 30 20 245B 74 72 61 6E 66 00 00 $ 61 0 $[tranf
00000032 56 53 00 00 39 01 00 566C 70 70 2D 73 79 6D 66 VS9Vlpp-symf
00000048 75 6E 2D 3E 61 6C 00 696E 74 65 72 6E 00 53 00 un->al intern S
00000064 00 39 02 00 39 02 00 3902 00 5B 73 65 74 00 00 999[set
00000080 34 02 03 02 16 24 4 $
看看,支持下 厉害,必须支持 感谢高大佬分享 感谢分享
感谢大师为lisp界做贡献
感谢分享....... 谢谢高飞版主 厉害,必须支持 太强大了,相当于增加了很多功能