home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
wps
/
editor
/
epmtools
/
epmsmp
/
ea.e
< prev
next >
Wrap
Text File
|
1992-10-16
|
29KB
|
640 lines
; Routines for manipulating extended attributes.
;
; EPM's .eaarea field contains a pointer to a buffer containing the
; extended attributes for the current file. This is an FEALIST; see
; the OS/2 Tech Ref for details. If the file was loaded from disk,
; the .eaarea will *always* contain a pointer to an FEALIST. If the
; file had no extended attributes, this FEALIST will contain nothing
; but a length field indicating an FEALIST length of 4.
;
; A newly created file in the editor will contain a .eaarea of 0 - i.e.
; a null pointer, indicating that the FEALIST does not exist.
;
; Don't forget - changing the .eaarea field or adding extended attributes
; does not affect the .modify field. If you want to ensure that the
; attributes are saved, you may want to explicitly increment .modify in
; your routines.
;
; by Larry Margolis
; Note: This file contains some duplicated and redundant functions; it's a
; toolkit of routines for playing with extended attributes. Extract what you
; need for your application. The "Dependencies" comment before each routine
; tells what other pieces you need from this file. Dependencies on routines
; from the base set of macros (e.g., entrybox(), winmessagebox() ) are not
; mentioned. Note that some of these routines are included in EPM_EA which
; is part of the base set of macros.
;
; Index:
; QEA Tells what the .eaarea is set to
; SHOW_EA Displays all extended attributes
; GET_EA Tells you the value for a given attribute name
; get_ea_value() Returns the value for a given attribute name
; get_ea_value2() As above, but uses find_ea() & only handles EAT_ASCII
; find_ea() Looks for a given attribute; sets lots of VAR parameters
; SET_EA Sets a single name / value pair in an empty .eaarea
; SET_EA_MANY Sets a number of name / value pairs in an empty .eaarea
; ADD_EA Adds a single name / value pair to an existing EA list
; GET_EA2 Like GET_EA, but uses find_ea() instead of get_ea_value()
; DELETE_EA Deletes a named extended attribute
; delete_ea() Deletes a named extended attribute
; TYPE Displays and optionally sets the .TYPE extended attribute
; SETFILETYPE Sets the .TYPE extended attribute to anything
; SUBJECT Displays and optionally sets the .SUBJECT extended attribute
; PUTFIELD Store a field (.filename, .userstring, etc.) in an EA.
; GETFIELD Set a field from the value previously saved in the EA.
const -- Some constants
EAT_BINARY = \254\255 -- FFFE
EAT_ASCII = \253\255 -- FFFD
EAT_BITMAP = \251\255 -- FFFB
EAT_METAFILE = \250\255 -- FFFA
EAT_ICON = \249\255 -- FFF9
EAT_EA = \238\255 -- FFEE
EAT_MVMT = \223\255 -- FFDF
EAT_MVST = \222\255 -- FFDE
EAT_ASN1 = \221\255 -- FFDD
-- Just see what the .eaarea is set to.
; Dependencies: None
defc qea = sayerror '.eaarea = '.eaarea '= x'ltoa(atol(.eaarea),16)
; Dependencies: None
defc showea, show_ea = -- Show all extended attributes
if abbrev('FILE', upcase(arg(1)), 1) then -- 'ShowEA F' to dump to a file
file_flag = 1
'xcom e /n'
if rc<>-282 then sayerror 'Could not open output file!'; return rc; endif
getfileid fid
.autosave = 0
prevfile
fid.titletext = '.eaarea of "'.filename'"'
else
file_flag = 0
fid = ''
endif
; ea_seg = .eaarea % 65536
; ea_ofs = .eaarea // 65536
ea_long = atol(.eaarea)
ea_seg = itoa(rightstr(ea_long,2),10)
ea_ofs = itoa(leftstr(ea_long,2),10)
if .eaarea then
ea_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
; insertline peek(ea_seg, ea_ofs, min(ea_len,255)), .last+1
else
ea_len = 0
endif
ea_output(file_flag, '.eaarea = '.eaarea '= x'ltoa(ea_long,16)'; ea_seg =' ea_seg '= x'itoa(atoi(ea_seg),16)'; ea_ofs =' ea_ofs'; ea_len = 'ea_len, fid)
ea_count = 0
ea_end = ea_ofs + ea_len
ea_ofs = ea_ofs + 4 -- Point past length of FEAList
do while ea_ofs < ea_len
ea_flag = itoa(peek(ea_seg, ea_ofs, 1)\0,16)
ea_namelen = asc(peek(ea_seg, ea_ofs+1, 1))
ea_valuelen = ltoa(peek(ea_seg, ea_ofs+2, 2)\0\0,10)
ea_name = peekz(ea_seg, ea_ofs+4)
if ea_valuelen then
ea_value = peek(ea_seg, ea_ofs+5+ea_namelen,min(ea_valuelen,255))
ea_datatype = rightstr(itoa(leftstr(ea_value,2),16),4,0)
ea_datalen = itoa(substr(ea_value,3,2),10)
ea_data = substr(ea_value,5)
else
ea_value = ''
ea_datatype = '????'
ea_datalen = 0
ea_data = ''
endif
ea_count = ea_count + 1
if leftstr(ea_value,2) = EAT_MVMT then
ea_output(file_flag, 'EA' ea_count 'flag=x'ea_flag 'name('ea_namelen')="'ea_name'"; type=x'ea_datatype' (MVMT); value('ea_valuelen') =', fid)
ea_codepage = ea_datalen
ea_numentries = itoa(leftstr(ea_data,2),10)
if ea_numentries=1 then
ea_entrylen = itoa(substr(ea_data,5,2),10)
ea_output(file_flag, 'CP' ea_codepage '1 entry: type=x'rightstr(itoa(substr(ea_data,3,2),16),4,0)'; len='ea_entrylen'; "'substr(ea_data,7,ea_entrylen)'"', fid)
else
ea_entry_ofs = ea_ofs+11+ea_namelen
ea_output(file_flag, 'CP' ea_codepage';' ea_numentries 'entries: (ofs='ea_entry_ofs')', fid)
do i=1 to ea_numentries
ea_entrylen = itoa(peek(ea_seg, ea_entry_ofs+2, 2),10)
; messageNwait( ' >> peeking at' ea_entry_ofs', entry' i 'type=x'rightstr(itoa(peek(ea_seg,ea_entry_ofs,2),16),4,0))
ea_entry = peek(ea_seg, ea_entry_ofs,min(ea_entrylen+4,255))
ea_output(file_flag, ' entry' i 'type=x'rightstr(itoa(leftstr(ea_entry,2),16),4,0)'; len='ea_entrylen'; "'substr(ea_entry,5)'"', fid)
ea_entry_ofs = ea_entry_ofs + ea_entrylen + 4
enddo
endif
elseif leftstr(ea_value,2) = EAT_MVST then
ea_output(file_flag, 'EA' ea_count 'flag=x'ea_flag 'name('ea_namelen')="'ea_name'"; type=x'ea_datatype' (MVST); value('ea_valuelen') =', fid)
ea_codepage = ea_datalen
ea_numentries = itoa(leftstr(ea_data,2),10)
if ea_numentries=1 then
ea_entrylen = itoa(substr(ea_data,5,2),10)
ea_output(file_flag, 'CP' ea_codepage'; type=x'rightstr(itoa(substr(ea_data,3,2),16),4,0) '1 entry: len='ea_entrylen'; "'substr(ea_data,7,ea_entrylen)'"', fid)
else
ea_entry_ofs = ea_ofs+13+ea_namelen
ea_output(file_flag, 'CP' ea_codepage'; type=x'rightstr(itoa(substr(ea_data,3,2),16),4,0) ea_numentries 'entries: (ofs='ea_entry_ofs')', fid)
do i=1 to ea_numentries
ea_entrylen = itoa(peek(ea_seg, ea_entry_ofs, 2),10)
; messageNwait( ' >> peeking at' ea_entry_ofs', entry' i
ea_entry = peek(ea_seg, ea_entry_ofs,min(ea_entrylen+2,255))
ea_output(file_flag, ' entry' i 'len='ea_entrylen'; "'substr(ea_entry,3)'"', fid)
ea_entry_ofs = ea_entry_ofs + ea_entrylen + 2
enddo
endif
else
ea_output(file_flag, 'EA' ea_count 'flag=x'ea_flag 'name('ea_namelen')="'ea_name'"; type=x'ea_datatype'; value('ea_valuelen','ea_datalen') =', fid)
ea_output(file_flag, '"'ea_data'"', fid)
endif
ea_ofs = ea_ofs + ea_namelen + 5 + ea_valuelen -- Point past length of FEAList
enddo
if file_flag then
fid.modify = 0
nextfile
endif
defproc ea_output(file_flag, outstr, fid)
if file_flag then
insertline outstr, fid.last+1, fid
else
sayerror outstr
endif
; Dependencies: get_ea_value()
defc getea, get_ea = -- Tells you the value for a given attribute name
parse arg name .
if name='' then
sayerror 'GET_EA <name> tells you the extended attribute value for the given attribute name.'
return
endif
val = get_ea_value(name)
if leftstr(val,2)=\253\255 then -- x'FFFD', after byte reversal
stuff = 'EAT_ASCII ('itoa(substr(val,3,2),10)') '
val = substr(val,5)
else
stuff = ''
endif
sayerror name'='stuff'"'val'"'
; Dependencies: None
defproc get_ea_value(name) = -- Returns the value for a given attribute name
; ea_seg = .eaarea % 65536
; ea_ofs = .eaarea // 65536
ea_long = atol(.eaarea)
ea_seg = itoa(rightstr(ea_long,2),10)
ea_ofs = itoa(leftstr(ea_long,2),10)
if not .eaarea then return ''; endif
ea_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
ea_end = ea_ofs + ea_len
ea_ofs = ea_ofs + 4 -- Point past length of FEAList
do while ea_ofs < ea_len
;; ea_flag = itoa(peek(ea_seg, ea_ofs, 1)\0,16)
ea_namelen = asc(peek(ea_seg, ea_ofs+1, 1))
ea_valuelen = itoa(peek(ea_seg, ea_ofs+2, 2),10)
if name = peekz(ea_seg, ea_ofs+4) then
if ea_valuelen then
return peek(ea_seg, ea_ofs+5+ea_namelen,min(ea_valuelen,255))
else
leave -- value length = 0; return null string
endif
endif
ea_ofs = ea_ofs + ea_namelen + 5 + ea_valuelen -- Point past length of FEAList
enddo
; Dependencies: find_ea
defproc get_ea_value2(name) = -- Returns the value for a given (EAT_ASCII) attribute name
if find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
return peek(ea_seg, ea_ptr2, min(ea_valuelen,255))
endif
; Returns 1 if attribute name exists; sets VAR args. EA_SEG, EA_OFS =
; start of EA buffer. EA_PTR1, 2 = pointers to start of entry and value,
; respectively, if name was found. EA_LEN, EA_ENTRYLEN, EA_VALUELEN = length
; of EA area, of entry, and of value, respectively.
; Dependencies: None
defproc find_ea(name, var ea_seg, var ea_ofs, var ea_ptr1, var ea_ptr2, var ea_len, var ea_entrylen, var ea_valuelen) =
ea_long = atol(.eaarea)
ea_seg = itoa(rightstr(ea_long,2),10)
ea_ofs = itoa(leftstr(ea_long,2),10)
if not .eaarea then return ''; endif
ea_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
ea_end = ea_ofs + ea_len
ea_ptr1 = ea_ofs + 4 -- Point past length of FEAList
do while ea_ptr1 < ea_len
; ea_flag = itoa(peek(ea_seg, ea_ptr1, 1)\0,16)
ea_namelen = asc(peek(ea_seg, ea_ptr1+1, 1))
ea_valuelen = itoa(peek(ea_seg, ea_ptr1+2, 2),10)
ea_entrylen = ea_namelen + 5 + ea_valuelen
if name = peekz(ea_seg, ea_ptr1+4) then
ea_ptr2 = ea_ptr1+5+ea_namelen -- Point to start of EA value
return 1
endif
ea_ptr1 = ea_ptr1 + ea_entrylen -- Point to start of next entry
enddo
; Dependencies: None
defc setea, set_ea = -- Sets a single name / value pair
parse arg name data
if name='' then
sayerror 'SET_EA <name> <value> sets the extended attribute value for a new file *only*.'
return
endif
name_len = length(name)
data_len = length(data)
ea_len = 13 + name_len + data_len
if .eaarea then
ea_long = atol(.eaarea)
ea_seg = itoa(rightstr(ea_long,2),10)
ea_ofs = itoa(leftstr(ea_long,2),10)
ea_old_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
if ea_old_len > 4 then
sayerror '.eaarea already set; this example is only for newly-created edit files.'
return
endif
r = dynalink('DOSCALLS', -- Dynamic link library name
'#38', -- DosReAllocSeg
atoi(ea_len) || -- Number of bytes requested
rightstr(ea_long,2) )
re = 're'
ea_ptr = ea_seg
else
ea_buffer = "00" -- Initialize string pointer.
r = dynalink('DOSCALLS', -- Dynamic link library name
'#34', -- DosAllocSeg
atoi(ea_len) || -- Number of bytes requested
selector(ea_buffer) || -- String selector
offset(ea_buffer) || -- String offset
atoi(0) ) -- Share information
re = ''
ea_ptr = itoa(ea_buffer,10)
endif
if r then sayerror 'Error' r re'allocating memory segment; command halted.'; stop; endif
poke ea_ptr, 0, atol(ea_len)
poke ea_ptr, 4, \0 -- Start of EA: flag byte
poke ea_ptr, 5, chr(name_len)
poke ea_ptr, 6, atoi(data_len + 4) -- Value length = len(data) + len(data_type) + len(data_len)
poke ea_ptr, 8, name
poke ea_ptr, 8+name_len, \0 -- Null byte after name
poke ea_ptr, 9+name_len, \253\255 -- EAT_ASCII
poke ea_ptr, 11+name_len, atoi(data_len)
poke ea_ptr, 13+name_len, data
.eaarea = mpfrom2short(ea_ptr,0)
; Dependencies: None
defc set_ea_many = -- Sets a bunch of attributes.
if arg(1)='' then
sayerror 'SET_EA_MANY /<name> <value>/<name> <value>/... sets extended attributes for a new file *only*.'
return
endif
parse arg delim 2 rest
ea_len = 4 -- Initialize to 4 bytes for FEALIST Length field
do while rest <> ''
parse value rest with stuff (delim) rest
parse value stuff with name data
ea_len = ea_len + length(name) + length(data) + 9 -- 9 bytes overhead per EA
enddo
if .eaarea then
ea_long = atol(.eaarea)
ea_seg = itoa(rightstr(ea_long,2),10)
ea_ofs = itoa(leftstr(ea_long,2),10)
ea_old_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
if ea_old_len > 4 then
sayerror '.eaarea already set; this example is only for newly-created edit files.'
return
endif
r = dynalink('DOSCALLS', -- Dynamic link library name
'#38', -- DosReAllocSeg
atoi(ea_len) || -- Number of bytes requested
rightstr(ea_long,2) )
re = 're'
ea_ptr = ea_seg
else
ea_buffer = "00" -- Initialize string pointer.
r = dynalink('DOSCALLS', -- Dynamic link library name
'#34', -- DosAllocSeg
atoi(ea_len) || -- Number of bytes requested
selector(ea_buffer) || -- String selector
offset(ea_buffer) || -- String offset
atoi(0) ) -- Share information
re = ''
ea_ptr = itoa(ea_buffer,10)
endif
if r then sayerror 'Error' r re'allocating memory segment; command halted.'; stop; endif
poke ea_ptr, 0, atol(ea_len)
parse arg delim 2 rest
ea_ofs = 4 -- Point to start of EA
do while rest <> ''
parse value rest with stuff (delim) rest
parse value stuff with name data
name_len = length(name)
data_len = length(data)
poke ea_ptr, ea_ofs , \0 -- Start of EA: flag byte
poke ea_ptr, ea_ofs+1, chr(name_len)
poke ea_ptr, ea_ofs+2, atoi(data_len + 4) -- Value length = len(data) + len(data_type) + len(data_len)
poke ea_ptr, ea_ofs+4, name
poke ea_ptr, ea_ofs+4+name_len, \0 -- Null byte after name
poke ea_ptr, ea_ofs+5+name_len, EAT_ASCII
poke ea_ptr, ea_ofs+7+name_len, atoi(data_len)
poke ea_ptr, ea_ofs+9+name_len, data
ea_ofs = ea_ofs + name_len + data_len + 9 -- 9 bytes overhead per EA
enddo
.eaarea = mpfrom2short(ea_ptr,0)
; Dependencies: None
defc addea, add_ea = -- Adds a single name / value pair to an existing EA list
parse arg name data
if name='' then
sayerror 'ADD_EA <name> <value> adds the extended attribute value specified to the current file.'
return
endif
name_len = length(name)
data_len = length(data)
ea_len_incr = 9 + name_len + data_len
if .eaarea then
ea_long = atol(.eaarea)
ea_seg = itoa(rightstr(ea_long,2),10)
ea_ofs = itoa(leftstr(ea_long,2),10)
ea_old_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
r = dynalink('DOSCALLS', -- Dynamic link library name
'#38', -- DosReAllocSeg
atoi(ea_old_len+ea_len_incr) || -- Number of bytes requested
rightstr(ea_long,2) )
re = 're'
ea_ptr = ea_seg
else
ea_buffer = "00" -- Initialize string pointer.
r = dynalink('DOSCALLS', -- Dynamic link library name
'#34', -- DosAllocSeg
atoi(ea_len_incr+4) || -- Number of bytes requested
selector(ea_buffer) || -- String selector
offset(ea_buffer) || -- String offset
atoi(0) ) -- Share information
re = ''
ea_ptr = itoa(ea_buffer,10)
ea_ofs = 0
ea_old_len = 4 -- Point past length field
endif
if r then sayerror 'Error' r re'allocating memory segment; command halted.'; stop; endif
poke ea_ptr, ea_ofs, atol(ea_old_len+ea_len_incr)
ea_ofs = ea_ofs + ea_old_len
poke ea_ptr, ea_ofs , \0 -- Start of EA: flag byte
poke ea_ptr, ea_ofs+1, chr(name_len)
poke ea_ptr, ea_ofs+2, atoi(data_len + 4) -- Value length = len(data) + len(data_type) + len(data_len)
poke ea_ptr, ea_ofs+4, name
poke ea_ptr, ea_ofs+4+name_len, \0 -- Null byte after name
poke ea_ptr, ea_ofs+5+name_len, EAT_ASCII
poke ea_ptr, ea_ofs+7+name_len, atoi(data_len)
poke ea_ptr, ea_ofs+9+name_len, data
.eaarea = mpfrom2short(ea_ptr,0)
; Dependencies: find_ea()
defc get_ea2, getea2 = -- Tells you the value for a given attribute name
parse arg name . -- (This version uses find_ea() instead of get_ea_value().)
if name='' then
sayerror 'GET_EA <name> tells you the extended attribute value for the given attribute name.'
return
endif
if find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
val = peek(ea_seg, ea_ptr2,min(ea_valuelen,255))
if leftstr(val,2)=\253\255 then -- x'FFFD', after byte reversal
stuff = 'EAT_ASCII ('itoa(substr(val,3,2),10)') '
val = substr(val,5)
else
stuff = ''
endif
sayerror name'='stuff'"'val'"'
else
sayerror '<Not found>'
endif
; Dependencies: find_ea()
defc delete_ea, deleteea =
parse arg name .
if name='' then
sayerror 'DELETE_EA <name> deletes the named extended attribute.'
return
endif
if not find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
sayerror '<Not found>'
return
endif
newlen = ea_len - ea_entrylen
poke ea_seg, ea_ofs, atol(newlen)
if ea_ptr1+ea_entrylen < ea_len then -- If in the middle, close it up
call memcpyx(atoi(ea_ptr1) || atoi(ea_seg), atoi(ea_ptr1+ea_entrylen) || atoi(ea_seg), ea_len - ea_ptr1 - ea_entrylen)
endif
r = dynalink('DOSCALLS', -- Dynamic link library name
'#38', -- DosReAllocSeg
atoi(newlen) || -- Number of bytes requested
atoi(ea_seg) )
;; if r then sayerror 'Error' r 'reallocating memory segment; command halted.'; stop; endif
; Dependencies: find_ea()
defproc delete_ea(name) =
parse arg name .
if not find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
return
endif
newlen = ea_len - ea_entrylen
poke ea_seg, ea_ofs, atol(newlen)
junk = 'junk' -- Avoid problem due to bug in MEMCPYX in EPM 5.20
if ea_ptr1+ea_entrylen < ea_len then -- If in the middle, close it up
call memcpyx(atoi(ea_ptr1) || atoi(ea_seg), atoi(ea_ptr1+ea_entrylen) || atoi(ea_seg), ea_len - ea_ptr1 - ea_entrylen)
endif
call dynalink('DOSCALLS', -- Dynamic link library name
'#38', -- DosReAllocSeg
atoi(newlen) || -- Number of bytes requested
atoi(ea_seg) )
; Dependencies: find_ea(), delete_ea(), add_ea
defc type =
found = find_ea('.TYPE', ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen)
if not found | ea_valuelen=0 then
answer = winmessagebox('Type', 'File has no type. Would you like to set one?', 16388) -- YESNO + MOVEABLE
elseif peek(ea_seg, ea_ptr2, 2)=EAT_ASCII then
type = peek(ea_seg, ea_ptr2+4, min(itoa(peek(ea_seg, ea_ptr2+2, 2), 10), 255))
answer = winmessagebox('Type', 'File has the following type:'\13 type\13\13'Would you like to change it?', 16388) -- YESNO + MOVEABLE
elseif peek(ea_seg, ea_ptr2, 2)=EAT_MVMT then
ea_numentries = itoa(peek(ea_seg, ea_ptr2+4, 2),10)
if ea_numentries=1 then
type = 'File has the following type:'
else
type = 'File has types:'
endif
ea_entry_ofs = ea_ptr2+6
do i=1 to ea_numentries
ea_entrylen = itoa(peek(ea_seg, ea_entry_ofs+2, 2),10)
if peek(ea_seg, ea_entry_ofs, 2)=EAT_ASCII then
type = type\13 || peek(ea_seg, ea_entry_ofs+4,min(ea_entrylen,255))
else
type = type\13 || '<non-ASCII>'
endif
ea_entry_ofs = ea_entry_ofs + ea_entrylen + 4
enddo
answer = winmessagebox('Type', type\13\13'Would you like to change it?', 16388) -- YESNO + MOVEABLE
else
answer = winmessagebox('Type', 'File has non-ASCII data for the type.'\13'Would you like to change it?', 16388) -- YESNO + MOVEABLE
endif
if answer=6 then
newtype = listbox('Select type','-Plain Text-OS/2 Command File-DOS Command File-C Code-Pascal Code-BASIC Code-COBOL Code-FORTRAN Code-Assembler Code-')
if newtype then
if found then call delete_ea('.TYPE'); endif
'add_ea .TYPE' newtype
endif
endif
; Dependencies: delete_ea(), add_ea
defc setattribute, setfiletype
call delete_ea('.TYPE')
'add_ea .TYPE' arg(1)
; Dependencies: find_ea(), delete_ea(), add_ea
defc subject =
found = find_ea('.SUBJECT', ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen)
subj = ''
if not found | ea_valuelen=0 then
answer = winmessagebox('Subject', 'File has no subject. Would you like to add one?', 16388) -- YESNO + MOVEABLE
elseif peek(ea_seg, ea_ptr2, 2)=EAT_ASCII then
subj = peek(ea_seg, ea_ptr2+4, min(itoa(peek(ea_seg, ea_ptr2+2, 2), 10), 255))
answer = winmessagebox('Subject', 'File has the following subject:'\13 subj\13\13'Would you like to change it?', 16388) -- YESNO + MOVEABLE
else
answer = winmessagebox('Subject', 'File has non-ASCII data for the subject.'\13'Would you like to change it?', 16388) -- YESNO + MOVEABLE
endif
if answer=6 then
newsubj = entrybox('Enter subject', '', subj, 40, 40)
if newsubj then
if found then call delete_ea('.SUBJECT'); endif
'add_ea .SUBJECT' newsubj
endif
endif
; The following routine will put the contents of the current file into the
; .EAarea of another file as an MVST EAT_ASCII attribute. If the given
; attribute name already exists, it will be replaced (not extended).
; Dependencies: delete_ea()
defproc put_file_as_MVST(source_fid, target_fid, ea_name)
getfileid start_fid
activatefile target_fid
call delete_ea(ea_name)
if not source_fid.last then -- If nothing to add,
activatefile start_fid
return -- we're all done.
endif
name_len = length(ea_name)
value_len = filesize() + 2 * .last + 8 -- Overhead: 2 bytes/rec length, + 2 bytes each EAT_MVST, codepage, numentries, EAT_ASCII
ea_len_incr = 5 + name_len + value_len -- Overhead: 1 flags, 1 len(name), 2 len(value), 1 null ASCIIZ terminator
if .eaarea then
ea_long = atol(.eaarea)
ea_seg = itoa(rightstr(ea_long,2),10)
ea_ofs = itoa(leftstr(ea_long,2),10)
ea_old_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
r = dynalink('DOSCALLS', -- Dynamic link library name
'#38', -- DosReAllocSeg
atoi(ea_old_len+ea_len_incr) || -- Number of bytes requested
rightstr(ea_long,2) )
re = 're'
ea_ptr = ea_seg
else
ea_buffer = "00" -- Initialize string pointer.
r = dynalink('DOSCALLS', -- Dynamic link library name
'#34', -- DosAllocSeg
atoi(ea_len_incr+4) || -- Number of bytes requested
selector(ea_buffer) || -- String selector
offset(ea_buffer) || -- String offset
atoi(0) ) -- Share information
re = ''
ea_ptr = itoa(ea_buffer,10)
ea_ofs = 0
ea_old_len = 4 -- Point past length field
endif
if r then sayerror 'Error' r re'allocating memory segment; command halted.'; stop; endif
poke ea_ptr, ea_ofs, atol(ea_old_len+ea_len_incr)
ea_ofs = ea_ofs + ea_old_len
poke ea_ptr, ea_ofs , \0 -- Start of EA: flag byte
poke ea_ptr, ea_ofs+1, chr(name_len)
poke ea_ptr, ea_ofs+2, atoi(value_len)
poke ea_ptr, ea_ofs+4, ea_name
poke ea_ptr, ea_ofs+4+name_len, \0 -- Null byte after name
poke ea_ptr, ea_ofs+5+name_len, EAT_MVST
poke ea_ptr, ea_ofs+7+name_len, atoi(0) -- Code page
poke ea_ptr, ea_ofs+9+name_len, atoi(source_fid.last) -- NumEntries
poke ea_ptr, ea_ofs+11+name_len, EAT_ASCII -- Each entry is of type ASCII
ea_ofs = ea_ofs + 13 + name_len
do i=1 to source_fid.last
getline line, i, source_fid
poke ea_ptr, ea_ofs, atoi(length(line))
poke ea_ptr, ea_ofs+2, line
ea_ofs = ea_ofs + length(line) + 2
enddo
.eaarea = mpfrom2short(ea_ptr,0)
activatefile start_fid
; EPM.Attributes will save EPM attributes listed in current file into the .EAarea
defc try_EPM_EA =
getfileid source_fid
call put_file_as_MVST(source_fid, source_fid, 'EPM.Attributes')
; Dependencies: delete_ea(), add_ea
defc putfield -- Put a field into an EA
field = upcase(strip(arg(1)))
if leftstr(field,1)='.' then
field=substr(field,2)
endif
if field = '' then
Sayerror 'Supported fields are: FIlename MArgins TAbs TItletext Userstring'
return
elseif abbrev('FILENAME', field, 2) then
parse value 'FILENAME' .filename with fieldname fieldvalue
elseif abbrev('MARGINS', field, 2) then
parse value 'MARGINS' .margins with fieldname fieldvalue
elseif abbrev('TABS', field, 2) then
parse value 'TABS' .tabs with fieldname fieldvalue
elseif abbrev('TITLETEXT', field, 2) then
parse value 'TITLETEXT' .titletext with fieldname fieldvalue
elseif abbrev('USERSTRING', field, 1) then
parse value 'USERSTRING' .userstring with fieldname fieldvalue
else
sayerror 'Unknown or unsupported field: 'field
return
endif
call delete_ea('EPM.'fieldname)
'add_ea EPM.'fieldname fieldvalue
; Dependencies: check_field()
defc getfield -- Recover a field from an EA
field = upcase(strip(arg(1)))
if leftstr(field,1)='.' then
field=substr(field,2)
endif
if abbrev('FILENAME', field, 2) then
.filename = check_field('FILENAME', .filename)
elseif abbrev('MARGINS', field, 2) then
.margins = check_field('MARGINS', .margins)
elseif abbrev('TABS', field, 2) then
.tabs = check_field('TABS', .tabs)
elseif abbrev('TITLETEXT', field, 2) then
.titletext = check_field('TITLETEXT', .titletext)
elseif abbrev('USERSTRING', field, 1) then
.userstring = check_field('USERSTRING', .userstring)
else
sayerror 'Unknown or unsupported field: 'field
return
endif
; Dependencies: get_ea_value()
defproc check_field(fieldname, current_value)
val = get_ea_value('EPM.'fieldname)
if leftstr(val,2)=\253\255 then -- x'FFFD', after byte reversal
return substr(val,5) -- (EAT_ASCII)
elseif val='' then
sayerror 'Field value not found in extended attribute area.'
else
sayerror 'Saved as unsupported EA type: 'itoa(leftstr(val,2),16)
endif
return current_value