Смекни!
smekni.com

Программирование и разработка приложений в Maple (стр. 61 из 135)

Вызов процедуры type(F, file) возвращает true-значение, если К – реально существующий файл данных, и false-значение в противном случае. При этом, следует иметь в виду, что возврат false-значения говорит лишь о том, что тестируемый файл не: (1) последний элемент в цепочке каталогов F, (2) в текущем каталоге и (3) среди открытых файлов. Ниже представлен исходный текст процедуры и примеры ее применения.

type/file := proc(F::anything) local a b c k f SveGal, , , , , ; global _datafilestate; if not type( ,F {'symbol', 'string'}) then return false else c := interface(warnlevel); null interface(( warnlevel = 0)) end if;

SveGal := proc( )f try open ,(f 'READ'); close( )f catch "file or directory does not exist":

RETURN(false, unassign '( _datafilestate')) catch "file or directory, %1, does not exist":

RETURN(false, unassign '( _datafilestate')) catch "file I/O error" RETURN(: false, unassign '( _datafilestate')) catch "permission denied" RETURN(: false, unassign '( _datafilestate')) end try ;

true, assign67('_datafilestate' = 'close', f)

end proc ; if Empty Red_n( ,( F " " 1, )) then null interface(( warnlevel = c)); ERROR "argument <%1> is invalid",( F)

else assign67(a = iostatus( ), b = NULL, f = CF(F)),

null(interface(warnlevel = c))

end if; if nops(a) = 3 then SveGal f( ), null interface(( warnlevel = c)) else for k in a[4 .. -1] do if CF(k[2]) = CF( )f then b := b, [k[1], k[2]] end if end do; if b = NULL then SveGal f( ), null interface(( warnlevel = c)) else true, assign67('_datafilestate' = 'open b', ), null interface(( warnlevel = c))

end if

end if

end proc

> map(type, ["C:/Temp/http.htm", "D:&bsol;Grodno&bsol;Maple1.doc", `C:/Program Files`,

`C:/Temp`, "D:&bsol;Academy&bsol;Books/GrGU/Program.pdf", "C:/Print&bsol;STV.doc"], 'file');

[true, true, false, false, true, true]

Между тем, тестируемый файл, вообще говоря, может быть элементом файловой системы компьютера. При этом, через глобальную переменную _datafilestate в случае возврата true-значения возвращается последовательность, чей первый элемент определяет состояние файла {close, open}, тогда как второй элемент для close-состояния определяет полный путь к найденному файлу, а для open-состояния – 2-элементный список, чей первый элемент определяет используемый файлом логический канал в/в, тогда как второй – полный путь к файлу. Средства нашей Библиотеки [41], имеющие дело с доступом к файлам данных, используют именно эту процедуру. Между тем, для более развитого тестирования Maple-объектов на предмет их принадлежности к file-типу предназначена процедура type(F, 'file1'), представленная ниже исходным текстом и примерами применения.

type/file1 := proc(F::anything) local a b k p t t1 t2 t3 h u, , , , , , , , , , ω;

`if` type(( eval(F), {'symbol', 'string', 'name'}), assign(b = iostatus( )),

RETURN(false));

ω, u := ( ) → ERROR("<%1> is invalid path to a directory or a file", F), interface(warnlevel); `if`(Red_n(cat " ",( F), " " 2, ) = " " or member( ,F {``, ""}), ω( ), null interface(( warnlevel = 0)));

assign(a = Red_n(Subs_All("/" = "&bsol;" Case(, cat "",( F)), 1), "&bsol;" 2, )), null interface(( warnlevel = u));

`if`(3 < length(a) and a[-1] = "&bsol;", assign('a' = a[1 .. -2]),

`if`(length(a) = 2 and a[-1] = ":" assign(, ' 'a = cat(a, "&bsol;")), NULL));

`if`(nops(b) = 3, NULL, seq(`if`(CF(a) = CF(b k[ ][2]), RETURN(true), NULL), k = 4 .. nops(b)))

;

`if`(type(holdof('hold'), 'set'('integer')), NULL, assign(t = 7)); if a[2 .. 3] ≠ ":&bsol;" then try assign67(h = cat(CCM( ), "&bsol;" "maplesys.ini", ), Close(h)); do

t1 := readline(h);

if t1[1 .. 5] = "UserD"then t1 := t1[15 .. -1]; Close(h); break end if

end do;

t1 t2 t3, , := cat(t1, "&bsol;", a), cat(CDM( ), "&bsol;", a), cat(CCM( ), "&bsol;", a); if {op(map(procname, [t1, t2, t3]))} ≠ {false} then RETURN(holdof '( restore', 7), true) end if;

`if`(nops(b) = 3, NULL, seq(`if`(

Search1(CF(b k[ ][2]), ,a ' 'p ) and p = ['right'],

RETURN(holdof('restore', 7), true), 7), k = 4 .. nops(b)))

catch "file or directory does not exist"RETURN(: false) catch "file or directory, %1, does not exist"RETURN(: false) end try end if; try Close(fopen(a, 'READ'))

catch "file already open": `if`(t = 7, holdof('restore', 7), NULL), RETURN(true) catch "file or directory does not exist":

`if`(t = 7, holdof('restore', 7), NULL), RETURN(false) catch "file or directory, %1, does not exist": `if`(t = 7, holdof('restore', 7), NULL), RETURN(false) catch "file I/O error": `if`(t = 7, holdof('restore', 7), NULL), RETURN(false) catch "permission denied":

`if`(t = 7, holdof('restore', 7), NULL), RETURN(false) end try ; `if`(t = 7, holdof('restore', 7), NULL), true end proc

> map(type, ["C:/Print/Info.rtf", "D:/Photo/Aladjev8.jpg"], 'file1'); ⇒ [true, true]

Вызов процедуры type(F, 'file1') возвращает true-значение, если F определяет реальный файл данных и false-значение в противном случае. При этом, следует иметь в виду, что возврат false-значения говорит лишь о том, что тестируемый файл не: (1) последний элемент в цепочке каталогов F, (2) в главном каталоге Maple, (3) в каталоге с Maple-ядром, (4) в каталоге Users и (5) среди открытых файлов. Между тем, тестируемый файл, вообще говоря, может быть элементом файловой системы компьютера. Вызов процедуры не именяет текущих атрибутов и состояния {open|close} тестируемых файлов. Процедура полезна при разработке приложений, имеющих дело с обработкой файлов данных.

Стандартные функции system и ssystem позволяют выполнять целый ряд довольно важных процедур, обеспечивая более эффективное программирование. Однако на некоторых операционных платформах не все системные команды доступны через данный механизм. Как правило, указанные Maple-функции имеют дело с файлами типов {'.exe', '.com'}, стандартно поставляемых с операционной системой. Между тем, множество таких файлов весьма обширно и содержит целый ряд весьма полезных средств, представляющих немалый интерес и при разработке приложений в Maple-среде. Следующие две процедуры com_exe1 и com_exe2 в полной мере решают вопрос пополнения операционной среды требуемыми системными командами. С описанием алгоритмов, реализуемых данными процедурами, можно ознакомиться в [41,103,109].

com_exe1 := proc(P::{0, 1, path}, L::path) local a b c f, , , ; global _TABprog __ABprog, ; if P = 1 then if type(_TABprog, 'table') then RETURN map(( op, [indices(_TABprog )])) else ERROR("_TABprog is inactive in the current Maple session") end if end if; if type(L, 'dir') and type(L, 'mlib') then assign(f = "$Art16Kr9$.m", c = interface(warnlevel)), null(interface(warnlevel = 0)) else ERROR "<%1> is not a Maple library",( L) end if; if P = 0 then march '( extract L `_TABprog.m` f', , , );

if type(f, 'file') then (proc( )f filepos ,(f 8), writebytes( ,f [95]), close( )f ; read f; delf( )f

end proc )( )f ;

RETURN null(( interface(warnlevel = c)), map(op, [indices(__ABprog )]), assign('__ABprog' = '__ABprog'))

else ERROR "_TABprog is absent in library <%1>",( L) end if

elif type(P, 'file') then assign(a = Ftype(P), b = CFF(P)[-1]) else null interface(( warnlevel = 0)), ERROR(

"the first factual argument must be zero or file, but has received - %1", P) end if;

if member(a, {".com" ".exe", }) then

_TABprog[cat(`` b, )] := readbytes(P, ∞); close(P) else ERROR("filetype must be {`.com`, `.exe`}, but has received - %1", a) end if;

UpLib(L, [_TABprog ]), null interface(( warnlevel = c));

WARNING "_TABprog of library <%1> has been updated by program <%2>"( , L, b) end proc com_exe2 := proc() local a b c d p k h, , , , , , ; if type(_TABprog table, ) then assign(a = WD( ), d = [ ], p = [ ], b = map(op, [indices(_TABprog )])); unassign '( AVZ14061942')

else ERROR("_TABprog is inactive in the current Maple session") end if;

if nargs = 0 then h := ;b goto(AVZ14061942 ) else if type(args 1[ ], {'list'({'string', 'symbol'}), 'set'({'string', 'symbol'})}) then

if Empty(args[1]) then h := map(op, [indices(_TABprog )]); goto(AVZ14061942 ) else for k in args 1[ ] do if member(cat " ",( k)[-4 .. -1], {".com" ".exe", }) then p := [op(p), cat(`` k, )]

else WARNING("<%1> is an inadmissible filename", k) end if

end do

end if else ERROR("the first factual argument %1 is invalid" args[1], ) end if; h := SoLists `intersect`:- (p b, ); if p = [ ] or h = [ ] then

ERROR "programs appropriate for uploading are absent"( ) end if

end if;

AVZ14061942; for k in h do

c := cat(a, "&bsol;", k); if not type( ,c 'file') then writebytes(c, _TABprog[k]); close(c); d := [op(d), k]

end if

end do;

if d ≠ [ ] then d, WARNING(

"programs %1 have been uploaded into the main Windows directory", d) else WARNING("the required programs are already in the Windows directory") end if

end proc

> com_exe1("C:&bsol;Windows&bsol;crc.exe","C:&bsol;lbz&bsol;userlib"); Warning, _TABprog of library <"C:&bsol;lbz&bsol;userlib"> has been updated by program <"crc.exe">n

> com_exe1(0, "C:&bsol;Temp/UserLib9/userlib"); ⇒ [tasklist.exe, kill.exe, tlist.exe, taskkill.exe]

Первым Р-аргументом вызова com_exe1(P, L) может быть полный путь к файлу данных типа {'.exe', '.com'} с системной командой или {0|1}-значение, определяющее режим проверки глобальной переменной _TABprog, созданной/обновленной процедурой. Вызов com_exe1(0, L) возвращает полные имена программ, сохраненных в таблице _TABprog, находящейся в Maple-библиотеке, адрес которой указан в L. Тогда как вызов процедуры com_exe1(1, L) возвращает список полных имен программ, находящихся в _TABprog и доступных в текущем сеансе. Наконец, вызов com_exe1(P, L) обновляет Maple-библиотеку L программой, полный путь к которой определяется Р-аргументом.

Процедура com_exe2, дополняя предыдущую, предназначена для дозагрузки требуемых программ в главный каталог Windows. Детальнее с данными средствами можно ознакомиться в [41,103] либо в справке по нашей Библиотеке [108,109].

Вызов процедуры E_mail(F, H) обеспечивает выбор корректных email-адресов из текстового файла, указанного первым аргументом F, с помещением их в выходной файл, указанный вторым аргументом Н. При этом, при отсутствии пути к принимающему файлу Н он создается с выводом соответствующего сообщения о созданном пути к Н-файлу.

E_mail := proc(InF::file, OutF::{string, symbol })

local In Out Art S G k p T V Kr R F Y Z E L t r, , , , , , , , , , , , , , , , , , ω ν, ;

`if`( not type(InF, 'rlb'), ERROR "<%1> is not a text datafile",( InF), `if`( not type(eval(OutF), {'symbol', 'string'}),

ERROR "<%1> is not a datafile path",( OutF), `if` type(( OutF, 'file'), assign(ω = OutF, L = [ ], t = 0), [

assign(ν = interface(warnlevel), L = [ ], t = 0),

null interface(( warnlevel = 0)), assign(ω = MkDir(OutF, 1)), null interface(( warnlevel = ν))]))); T := {45 46 (, , 64 + k) $ (k = 0 .. 58), (48 + k) $ (k = 0 .. 9)} minus {64, 91, 92, 93, 94, 96}; [assign(Art = time( ), S = readbytes(InF, 'TEXT', ∞), R = 0), close(InF), assign(G = cat " ",( S, " "))], `if` search( ,( S "@"), NULL, ERROR("datafile <%1> does not contain email addresses", InF)), assign(V = [seq(`if`(G k[ ] = "@", ,k NULL), k = 1 .. length(G))]); for k in V do

assign('Kr' = "@", ' 'p = k); do p := p − 1; if member(op convert(( G p[ ], 'bytes')), T) then Kr := cat(G p[ ], Kr) else p := k; break

end if

end do;

do

p := p + 1; if member(op(convert(G[p], 'bytes')), T) then Kr := cat(Kr, G[p]) else break end if

end do;

`if`(Kr[1] = "@" or searchtext(".", Kr, searchtext("@", Kr) .. length(Kr)) = 0, assign(' 'R = R + 1, ' 'F = 61, ' 'Y = 4), NULL);

if F = 61 or Kr[-1] = "." or not search(Kr[-4 .. -2], ".") then writebytes(cat(substring(InF, 1 .. -4), "$$$"), Kr), writebytes( cat(substring(InF, 1 .. -4), "$$$"), `if`(2 < nargs [10] [, , 44 32, ])), assign('E' = 3), unassign('F') else assign(' 'L = [op(L), Kr]), assign(' 'Z = 12) end if

end do;

[assign(' 't = nops(L)), assign(' 'L = map(Case, {op(L)})), assign(' 'r = nops(L))]

; for k to nops(L) do writebytes(ω, L k[ ]), writebytes(ω, `if`(2 < nargs [10] [, , 44 32, ]))

end do; close `if`(( Z = 12, ω, NULL),

`if`(Y = 4, cat(substring(InF, 1 .. -4), "$$$"), NULL));

WARNING("%1 - total of constructions `@` in datafile <%2>

%3 - quantity of correct email addresses in datafile <%4>

%5 - quantity of multiple email addresses

%6 - quantity of suspicious email addresses in datafile <%7> run time of the procedure = %8 minute(s)", nops(V), InF, r, ω, t − r, R, cat(substring(InF, 1 .. -4), "$$$"), round(1/60×time( ) − 1/60×Art))

end proc

> E_mail("C:&bsol;RANS&bsol;My_email.txt", "C:&bsol;RANS&bsol;/Email&bsol;Email.txt", 10); Warning, 20 - total of constructions `@` in file <C:&bsol;RANS&bsol;My_email.txt>

20 - quantity of correct email addresses in file <C:&bsol;RANS&bsol;Email&bsol;Email.txt> 0 - quantity of multiple email addresses

0 - quantity of suspicious email addresses in file <C:&bsol;RANS&bsol;My_email.$$$> run time of the procedure = 0 minute(s)

Путь к файлу Н создается ранее рассмотренной процедурой MkDir [41,103,109]. Результатом выполнения процедуры является не только создание текстового файла с искомыми email-адресами, пригодными для немедленного использования средствами email, но и обеспечение основной статистики, чье назначение легче проясняет фрагмент, представленный выше. При этом, если вызов процедуры E_mail(F, H, h) использует необязательный третий h-аргумент (любое допустимое Maple-выражение), то каждый корректный email-адрес выводится в принимающий Н-файл отдельной строкой; в противном случае адреса разделяются запятой. Все подозрительные адреса (если такие существуют) помещаются в отдельный текстовый $$$-файл, чье главное имя идентично имени исходного F-файла. Процедура выводит и другую полезную статистику о результатах работы.