source: trunk/src/netlabs/macros/linkcmds.e@ 2652

Last change on this file since 2652 was 2652, checked in by Andreas Schnellbacher, 9 years ago
  • Added a message for successfully unlinking an .ex file.
  • Added trailing punctuation to messages.
  • Property svn:keywords set to Date Revision Author HeadURL Id
File size: 11.2 KB
Line 
1/****************************** Module Header *******************************
2*
3* Module Name: linkcmds.e
4*
5* Copyright (c) Netlabs EPM Distribution Project 2002
6*
7* $Id: linkcmds.e 2652 2015-11-15 19:00:26Z aschn $
8*
9* ===========================================================================
10*
11* This file is part of the Netlabs EPM Distribution package and is free
12* software. You can redistribute it and/or modify it under the terms of the
13* GNU General Public License as published by the Free Software
14* Foundation, in version 2 as it comes in the "COPYING" file of the
15* Netlabs EPM Distribution. This library is distributed in the hope that it
16* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
17* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18* General Public License for more details.
19*
20****************************************************************************/
21
22; ---------------------------------------------------------------------------
23; A front end to the link statement. This command should always be used in
24; preference to the link statement.
25; Without a given modulename, it tries to link the corresponding .ex file
26; of the current viewed .e file.
27; The QUIET option suppresses messages, when linking was successful or
28; module was already linked.
29; The Link command is also executed, when an .EX file is dropped onto the
30; edit window.
31; Syntax: link [QUIET] [<path>][<modulename>][.ex] Example: link draw
32; Sets rc:
33; 0 not linked, because already linked or because of another error
34; <0 error, rc = -307|-308 (message is shown, even for QUIET option)
35; >=0 linked successfully, the linked module number is returned, starting
36; with 0 for EPM.EX, followed by 1 etc.
37defc link
38 universal menuloaded -- only defined in newmenu yet
39
40 args = arg(1)
41 wp = wordpos( 'QUIET', upcase( args))
42 fQuiet = (wp > 0) |
43 (menuloaded <> 1) -- quiet if menu not already loaded
44 if wp then
45 args = delword( args, wp, 1) -- remove 'QUIET' from args
46 endif
47
48 modulename = args
49 if modulename = '' then -- If no name given,
50 p = lastpos( '.', .filename)
51 if upcase( substr( .filename, p)) <> '.E' then
52 sayerror 'Not an .E file'
53 return
54 endif
55 modulename = substr( .filename, 1, p - 1) -- current file without extension
56 p2 = lastpos( '\', modulename)
57 modulename = substr( modulename, p2 + 1) -- strip path
58 endif
59
60 ErrorText = link_common( modulename) -- sets rc
61
62 if (rc < 0) | (not fQuiet & rc >= 0) then
63 sayerror ErrorText
64 endif
65
66; ---------------------------------------------------------------------------
67; Like defc link, but in case of an error a MessageBox pops up, where the
68; user has to press 'OK' in order to continue. Other messages are always
69; suppressed. Additionally, the modulename must be given.
70defc linkverify
71 modulename = arg(1)
72
73 ErrorText = link_common( modulename) -- sets rc
74
75 if rc < 0 then
76 call winmessagebox( UNABLE_TO_LINK__MSG '"'modulename'", rc = 'rc'.',
77 ErrorText,
78 16416) -- OK + ICON_EXCLAMATION + MB+MOVEABLE
79 endif
80
81; ---------------------------------------------------------------------------
82; Returns ErrorText. Sets rc. rc = 0 if already linked. rc >= 0 on success.
83defproc link_common( modulename)
84 universal nepmd_hini
85
86 if nepmd_hini <> '' then
87 -- NEPMDLIB.DLL is used to resolve the bootdrive.
88 -- Skip resolving if not already loaded.
89 call parse_filename( modulename)
90 endif
91
92 waslinkedrc = linked( modulename)
93 if waslinkedrc >= 0 then -- >= 0, then it's the number in the link history
94 ErrorText = 'Module "'modulename'" already linked as module #'waslinkedrc'.'
95 xrc = 0 -- if already linked
96
97 else
98 -- NewMenu uses this to remove some of its menu items, before
99 -- an external package with a huge menu is linked.
100 -- Note: A dprintf won't work here. EPM won't start then.
101 -- In that case, delete your EPM.EX.
102 if isadefproc( 'BeforeLink') then
103 call BeforeLink( modulename)
104 endif
105
106 display -2 -- Turn non-critical messages off, we give our own message.
107 link modulename
108 linkrc = rc
109 -- Maybe rc of the link statement was changed by the module's
110 -- definit code before rc is queried after the link line above.
111 -- Therefore it's checked again with linked().
112 linkedrc = linked( modulename)
113 display 2
114
115 -- Link returns rc >= 0 if successful, like linked(). But
116 -- sometimes also rc = (null) is returned on success.
117 if linkedrc = -307 then
118 ErrorText = 'Module "'modulename'" not linked, file not found.'
119 elseif linkedrc = -308 then
120 ErrorText = 'Module "'modulename'" not linked, invalid filename.'
121 elseif linkedrc < 0 then
122 -- Use linkrc, because it's more detailed. linked() returns only
123 -- >=0, -1, -307, -308, while link returns some more like -290.
124 ErrorText = 'Module "'modulename'" not linked, 'sayerrortext(linkrc)'.'
125 else
126 ErrorText = LINK_COMPLETED__MSG''linkedrc' "'modulename'"'
127 endif
128
129 if linkrc < 0 & linkrc <> '' then
130 xrc = linkrc -- use the more detailed rc from link
131 else
132 xrc = linkedrc -- use the linked module # from linked()
133 endif
134
135 -- NewMenu uses this to re-add some of its menu items, after
136 -- an external package with a huge menu was not linked successfully.
137 if isadefproc( 'AfterLink') then
138 call AfterLink( xrc)
139 endif
140
141 endif -- waslinkedrc >= 0 else
142
143 rc = xrc
144 return ErrorText
145
146; ---------------------------------------------------------------------------
147; The following doesn't work. Dropping .ex files is always processed internally.
148; defc DragDrop_EX
149; 'link' arg(1) -- better use the defc
150;
151; defc DrgDrpTyp_EX_FILE
152; 'link' arg(1) -- better use the defc
153
154; ---------------------------------------------------------------------------
155; Syntax: unlink [<path>][<modulename>][.ex] Example: unlink draw
156; A front end to the unlink statement to allow command-line invocation.
157; The standard unlink statement doesn't search in EPMPATH and DPATH like the
158; link statement does. This is added here. ExFile is searched in
159; .;%EPMPATH%;%DPATH% until the linked file is found.
160defc unlink
161 FullPathName = ''
162 ExFile = arg(1)
163
164 call parse_filename( ExFile)
165
166 if substr( ExFile, 2, 2) = ':\' or substr( ExFile, 1, 2) = '\\' then
167 FullPathName = ExFile
168 endif
169
170 if FullPathName = '' then
171
172 -- If no name given, use current file with '.ex' extension
173 if ExFile = '' then
174 p2 = lastpos( '.', .filename)
175 if upcase( substr( .filename, p2)) <> '.E' then
176 sayerror '"'.filename'" is not an .E file'
177 return
178 endif
179 ExFile = substr( .filename, 1, p2 - 1)'.ex'
180 endif
181
182 -- Strip path and append '.ex' if no extension
183 p1 = lastpos( '\', ExFile)
184 ExFileName = substr( ExFile, p1 + 1)
185 p2 = lastpos( '.', ExFileName)
186 if p2 = 0 then
187 ExFileName = ExFileName'.ex'
188 endif
189
190 -- Search ExFile in whole PathList, until linkedrc >= 0
191 PathList = '.;'Get_Env('EPMPATH')';'Get_Env('DPATH')';' -- standard EPM
192 --PathList = Get_Env('EPMEXPATH')';' -- NEPMD
193 rest = PathList
194 do while rest <> ''
195 parse value rest with Path';'rest
196 if Path = '' then
197 iterate
198 endif
199 next = strip( Path, 'T', '\')'\'ExFileName
200 if Exist( next) then
201 linkedrc = linked( next)
202 if linkedrc >= 0 then
203 FullPathName = next
204 leave
205 endif
206 endif
207 enddo
208
209 endif
210
211 if FullPathName = '' then
212 FullPathName = arg(1) -- try to unlink arg(1) if not found until here
213 endif
214
215 display -2 -- Turn non-critical messages off, we give our own message.
216 unlink FullPathName
217 unlinkrc = rc
218 display 2
219 if unlinkrc then
220 if unlinkrc = -310 then
221 sayerror 'Module "'FullPathName'" not unlinked, unknown module.'
222 elseif unlinkrc = -301 then
223 sayerror 'Module "'FullPathName'" not unlinked, module in use (better restart EPM).'
224 elseif unlinkrc = -302 then
225 sayerror 'Module "'FullPathName'" not unlinked, defined keyset in use (better restart EPM).'
226 else
227 sayerror 'Module "'FullPathName'" not unlinked, rc = 'unlinkrc'.'
228 endif
229 else
230 sayerror 'Module "'FullPathName'" successfully unlinked.'
231 endif
232
233; ---------------------------------------------------------------------------
234; New command to query whether a module is linked. Of course if
235; you're not sure whether a module is linked, you can always just repeat the
236; link command. E won't reload the file from disk if it's already linked, but
237; it will rerun the module's DEFINIT which might not be desirable.
238;
239; This also serves to document the new linked() function. Linked() returns:
240; module number (a small integer, >= 0) if linked.
241; -1 if found on disk but not currently linked.
242; -307 if module can't be found on disk. This RC value
243; is the same as sayerror("Link: file not found").
244; -308 if bad module name, can't be expanded. Same as
245; sayerror("Link: invalid filename").
246defc qlink, qlinked, ql
247 module = arg(1)
248 call parse_filename( module)
249
250 if module = '' then
251 sayerror QLINK_PROMPT__MSG
252 else
253 result = linked( module)
254 if result = -307 or -- sayerror("Link: file not found")
255 result = -308 then -- sayerror("Link: invalid filename")
256 sayerror CANT_FIND1__MSG module CANT_FIND2__MSG
257 elseif result < 0 then -- return of -1 means file exists but not linked
258 sayerror module NOT_LINKED__MSG
259 else
260 sayerror module LINKED_AS__MSG result'.'
261 endif
262 endif
263
264; ---------------------------------------------------------------------------
265; Routine to link an .ex file, then execute a command in that file.
266defproc link_exec( ex_file, cmd_name)
267 'linkverify' ex_file
268 if rc >= 0 then
269 cmd_name arg(3) -- execute cmd_name with optional args
270 else
271 sayerror UNABLE_TO_EXECUTE__MSG cmd_name', module 'ex_file' not linked.'
272 endif
273
274; ---------------------------------------------------------------------------
275; Like link_exec, but checks first if cmd_name is defined. If not, ex_file
276; is linked before. Should be a bit faster than link_exec. cmd_name must be
277; be different from the name for the calling command.
278defproc link_exec2( ex_file, cmd_name)
279 if not isadefc( cmd_name) then
280 'LinkVerify' ex_file
281 if rc < 0 then
282 stop
283 endif
284 endif
285 cmd_name arg(3) -- execute cmd_name with optional args
286
287; ---------------------------------------------------------------------------
288defc linkexec
289 parse arg ex_file cmd_name
290 call link_exec( ex_file, cmd_name)
291
Note: See TracBrowser for help on using the repository browser.