وو

وحید آنلاین . آرشیو وبلاگ وحیدمی دات آی آر . شرکت بیان. vahidmy.blog.ir

وو

وحید آنلاین . آرشیو وبلاگ وحیدمی دات آی آر . شرکت بیان. vahidmy.blog.ir

§_or_$


§_or_$  ....



RosAsm notations never assume any typing (just like NASM). So you have to always specify some markers. Many older programmers, who are accustomed to MASM, do not like this at all, and consider it as an added pain to have to regularly specify the size, the type, and so on... They usually prefer declaring a symbol as 'type defined' and go on. 


The result of typing is unreadability. The advantage of having no typing at all and markers in all places instead is that we never have to search for what a given symbol is. This is extremely time saving, for the programmer, for future readers, and also, for the compiler, as, for example, when it encounters some &TRUE, there is no need to search what kind of symbol it is. First char > Win Equate > done. It's just the same for YOU as reader of your own writings, two months later...


Two characters are available for defining the size of accessed Values: Paragraph characters and Dollar character. (These two same characters are to be used to define Data Declarations):


mov eax D§ebx  |  sub bl B$MyCount


RosAsm actually subtitutes  $  to  §  ,so that the two keyboard inputs are equivalent on the screen.


This is to replace the old killing:


mov eax, DWORD PTR[ebx]  |  sub bl, BYTE PTR[MyCount]


Note: Given the importance of this notation in the overall RosAsm syntax design, the replacement of '§' by '$' is performed directly by intercepting the keyBoard input. An inconvenience comes with this technical choice: When you'd like to really type a '§' character, say, inside a String, you will have to explicitely write, for example:


[Data: B$ 'I'm using ', 167, '...'] 


, instead of


[Data: 'I'm using $...']


If you do not want, at all, of this substitution, just set the [With $ Marker only] Flag in the Configuration Tab [Sources Editor] Dialog.


I provide two signs in order to make it easy on all national Keyboards. Just choose the easiest one for you.


The '@' sign may be used the same way for Local_Symbols definitions and evocations.


Now, for beginners: Why do we have to tell the size? Lets look at this with a very common example:


cmp  D§ebp+12  &WM_COMMAND


Here we mean to compare the ''contents'' of an address pointed by ''ebp+12''. In this example, ebp points to the stack. Ebp value could be, for example,  063FF78 hexa, this is to say to one particular place in a particular memory reserved for Stack operations.


Now, we want to compare the value written in that place with WM_COMMAND  value (0111 hexa). 


If you are a pure beginner, it may be you do not have a really clear idea of what is a memory address and what is a value in memory. If so, imagine your computer's memory as a wide set of little boxes one after another. Some registers (eax, ebx, ...) may be managed, either by you, or directly by the processor's instructions, to point to what little box is actually going to be read or written to. This is the Pointer concept:


mov eax ebp    ; < eax = 063FF78 hexa.This is the pointer.

mov eax D§ebp ; < eax = value previously stored at the pointed to address.


If we just type something like:


cmp [ebp+12]  &WM_COMMAND


RosAsm (or any other Assembler) couldn't guesss if we intend to compare a byte with 0111, a word with 0111, or a dWord with 0111. In this example, if D$ebp+12 value were 0_A200_0111, W$ebp+12 would be equal to 0111, whereas D$ebp+12 would be greater.


~~~~~~~

Win32 specifics


Win32 specifics   ..



Api calls


In most other languages, api calls are done using 2 instructions (a CALL to a JMP instruction) because of problems bound to linker use (languages can't know where linkers will store the import table). RosAsm does it in one single instruction (CALL 'mem'). The syntax is, for example:


call 'KERNEL32.VirtualAlloc'


Evocations of apis do not need any previous declarations. When RosAsm finds a call 'SOME.Thing', it creates the wished entry in the Import table; that's all. The DLL name is not optional, unless you already provided it somewhere else. You must usually give, even in simple cases like 'COMCTL.InitCommonControls'. The counterpart of this simplicity is that you have to write the true full names of functions, at least one time in your Sources:


call 'User32.DispatchMessageA'  msg    ; With the 'A'


and not:


call 'DispatchMessage' msg


... unless  call 'User32.DispatchMessageA'   is already available somewhere else in your Source File. In such cases, RosAsm does the wanted operation silently.


For calling Functions in other Files than DLLs, this is directly available for *.drv, *.sys, *exe Files. For other exotic Files, you have to provide the extension by yourself:


call 'EXOTIC.fth.Function' msg


The great thing with this is that you will never have to browse on the Net to find some missing '.Lib' or '.Inc' (MASM users know what I mean, right? ;)


If you do not know what DLL a Function is from, just Right-Click on the Function name. RosAsm will open a Dialog with the full call. An internal List contains almost all of Api Function calls. If not found, take a look in the Win32 Help File and click on the [Quick Info] of the Function.The name of the 'Lib' is also the name of the DLL.


Upper cases for dlls' names are optional, but cases for Functions' names must be the true ones -apis are case sensitive-. This is one reason why apis need a specific calling writing convention. 


RosAsm now tests api calls with 5 possible error messages: Bad DLL / Bad Function / Missing 'A/W' / Exceeding A/W / bad api call form. Parameters number is not controlled, but, when you [Run] your application (Run includes a Debugger), run time errors that the debugger fails to point out are usually such errors.



Simplified Api calls


Once you have written one call to some DLL Function, in the complete format, as discribed above, you can omit the DLL Name. That is, you provide the DLL name, at least once, and this is enough to make the Assembler happy, for the other shots:



call 'KERNEL32.VirtualAlloc'      ; One complete version...

...

call 'VirtualAlloc'      ; Shortened form allowed.



Api call Error pointing


When the Assembler sends one of the Api Function error Messages, at the time of this computing, it is not working directly on a version of the original Source, but on a couple of tables used to encode the .Import Section. So, at the time of this error warning, the Assembler cannot know where the wrong Statement is in the real Source. Hence, it performs a simple search, from the Top of Source, the same way you would do it when using the [Find] Box. This is why, if, for example, a comment says the same thing, before the targeted call, the error Manager will point to the first (and wrong) instance of the searched name, inside the comment. In normal programming circumstances, this should not be a big problem. This mis-behaviour will be fixed later, when we will implement the Search Type in the [Find/Replace] feature.



Entry Point


Entry point must be called 'Main:'. If you do not like it, change the string at 'EntryPointLabel:'  and recompile > you got the eg. Change the 'Main:'  label in RosAsm's own source too and recompile again > you got the hen (sometimes a rooster). If you plan to modify some other points, try to fully understand why two compile times are needed here. Auto-compiling needs sometimes killing procedures...


The Win main loop for messages holding (what others usually call 'WinProc') must be named 'MainWindowProc' (same upper comment).



Win32 Equates


RosAsm knows more than 53,000 Win32 Equates . You just need to write a leading '&' at evocations (ex: &TRUE). This list covers all usual needs and much more. For non supported symbols, declare them as user Equates.


Win Structures are provided in an external File. To get a Structure, just run the Dialog associated with the [Struct] menu item. 



Win32 Structures


When translating sources from MASM to RosAsm, you will notice that many MASM users declare these Structures as Stack Local Data and then initialize the Structures' values at Run time. This is particularly stupid in most cases. Declare your Structures as any common Data sets and initialize everything you can at writing time, instead.  This is much easier to write, easier to read and faster to run. The only case in which Structures are welcome on the stack is when the given Structure is filled by Win32 to give us infos.


Another way of pointing to Structures (when some Structure Pointer is returned by Win32) is to replace the Structure Data by a Structure Equates Set. See a good example in ToolBar T.D. demo for TB_NOTIFY / TOOLTIPTEXT structure:



[TOOLTIPTEX:

  @hdr:  @NMHDR_hwndFrom: D§ 0

  @NMHDR_idfrom: D§ 0

  @NMHDR_code: D§ 0

  @lpszText: D§ 0]

   [@szText: B§ 0 #80]

   [@hInst: D§ 0

    @uFlags: D§ 0]


May be replaced by an EBX based pointers Equates set (the value to be set in EBX, in this case, is given by Win32 in a Message event):


[TOOLTIPTEXT_NMHDR_hwndFrom ebx

 TOOLTIPTEXT_NMHDR_idfrom    ebx+4

 TOOLTIPTEXT_NMHDR_code      ebx+8

 TOOLTIPTEXT_lpszText        ebx+12

 TOOLTIPTEXT_szText        ebx+16

 TOOLTIPTEXT_hInst          ebx+96

 TOOLTIPTEXT_uFlags          ebx+100]


Various forms of each Structure are given to you by the [Struc]. See Structures. There is also a little Dialog [Tool] / [Data to Equates] that may help you in doing these simple translations from your own Data form Structures.


~~~~~~~



RosAsm Specifics


RosAsm Specifics  ..

        

        

Multi instructions lines

        

mov eax ebx | mov ecx 0 | call My_Routine    ;   ' | ' and 'CR/LF' are equivalent



Multi lines instructions

        

          My_Macro_Evocation,       ; this is a macro evocation with 3 parameters:

                    AAA1,                        ; First one

                      BBB2,                       ; Second one

                        CCC3                     ; Third one

                        

                                                     ; commas mean 'not over...'



All source text that is not purely encodable instructions is inside square  brackets: Data, Equates and Macros

          

Data:      [First_value: 36  List_of_values: 44 126 32]

          

Equates:  [true 1  false 0]

          

Macro:    [Simple_Storage | mov al B§esi | mov ah B§esi+1]


          

RosAsm looks at the first separator sign following the first name inside square brackets:

          

Space >>>   equates

Colon >>>   data

Pipe or CR/LF >>>   macro

        


For Addressing syntax, see Data_Access.


Basically, any symbol (like with NASM) is an Address, and nothing else. To access a Value at a given symbolic Address, you have to provide the Size marker (D$Symbol / W$Symbol / B$Symbol). This makes the overall syntax clean, clear and univoque.



Comments


Like in most Assemblers, Comments begin  with a Semi-Colon and go up to the end of line:


; This is a Comment.


You can also have Multi-Line Comments with Double-Semi-Colons, alone one a line, at first  row:


;;

This is

     a Multi-Lines

            Comment.

;;


Internally (for the Editor and for the Assembler, the MLC (Multi-Line Comment) Marker is in fact 'LF ; ; CR'. That implies that the Double-Semi-Colons have to come alone on a single Line, First row, CR/LF ended. Anyway, the Editor colors will save you from any  typing errors with this.


As opposed to Square Brackets and Strings Quotes, the Double-Semi-Colons do not require to be paired. For example, you may end your Source with a 'To-Do' List, just beginning by an open (never closed) Double-Semi-Colons.


~~~~~~~



Syntax flexibility


Syntax flexibility  ....

          

          

RosAsm not only works on multi-instruction lines and multi-line instructions but it gives some new features for source text organization:

          

Comma sign ',' doesn't mean anything but 'Not over...' in multi line instructions and 'not one word' before signed numbers. So, it makes it  possible to use commas where you want, as many times as you want. All  following statements are good:

          

mov eax ebx | mov eax,ebx | mov,,,,,     eax,,,,,,,,ebx


The main reason why assemblers need the comma sign is here:   | mov D§eax  -4 | In this case, the text parser would suppress the true separator space (just like in   | mov D§eax - 4  ecx |  ), so that  | mov D§eax-4 | produces an error. Of course, in RosAsm too, you will have to write:  | mov eax, -4 | but, as this is the only one case where a comma is needed, I don't consider it a good reason to make it a rule. (you can as well write: | mov D§eax 0-4 | you can, of course, put commas everywhere -the old way- if you prefer to). I recommend the | mov eax 0-4 | formulation.


Commas are not required inside square brackets (to tell the Parsers that the Bracket Statement(s) is (are) not over), even if you insert blank lines or comments. Pay attention that freedom and flexibility in source writing has some counterpart: RosAsm has a few controls on mistakes like :


[open_bracket


In some (rare) cases this error may not be found. It could be done but flexibility would be decreased.


          


Out of Win32 Equates Names and text expressions, The sign '_' is given  'free of meaning' to draw lines,


________________________  =  ; ___________________________


and to insure clear writing:

          

My_Value = myvalue = M_Y___V_A_L_U_E 

 

all these forms will refer to the same internal symbolic: 'MYVALUE'. Particularly useful for binary numbers:

          

00_1010_1111_0000_0011  = 001010111100000011


'_' sign is simply stripped off by the text parser and does not appear in further  treatments with one important exception: The integrated Win Equates '_' signs are NOT stripped off and are really meaningful.


         

Spaces are fully controlled by the parser, so that:

          

mov ah b§si+1

mov ah b§ si + 1

mov ah,  b§ si     +  1

          

are all equivalent. Spaces are the true separators between the components of a statement, but the text parser is able to strip off the meaningless ones.


Note for the advanced search features of the Source_Editor: If you write


[MyData : 0]


My_Proc :

....


with a space before the colon, Right click search and tree view will not find these labels because these features apply on your real text.

          

          

RosAsm is a one pass model from the theoretical encoding point of view, but in its global way of working, it is a multi-pass (many passes, in fact). So, you can organize your source file the way you want; even macros and equates at last, entry point at first or about end and so on. The only one counterpart is that you can't redefine equates.

~~~~~~~


Naming


Naming  ....



RosAsm algorithms for Equates and Macros replacements use the Byte high bit as a flag. So you can't use for symbols namings ASCII Characters higher than 127. In Practice: 'a' > 'Z'. There is no error check for this.


RosAsm is case insensitive. (Case sensitive Api calls are 'Text').


Out of Mnemonics and Registers names, the reserved symbols are:


[  ]  Data, Equates, Macros Declarations.

{ } Nested declarations.


D$  B$  W$ Q$  R$  F$  T$  O$  X$  for declarations and addressings


=   is reserved for Equates alternate syntax. If you want to reuse this symbol for something else, just declare it at first position, just after the '['. 

RosAsm considers this symbol as Alternate Equates forms only when it is between two spaces. (  [=  =  e]  works as expected).


Align is reserved for Code Alignment. 


DB, inside Code, is reserved for Hexa Bytes Declarations/Reservations.


Main and MainWindowProc are reserved for Win32 model sources organization.


The point character may be used inside name. (you may even declare, for example, a Macro which name is only one point).


The '_' character  is stripped by the Source Parser and counts for nop. It remains significant only in cases of text (Api calls, for example) and of Win Equates.



Naming in mono-file Programming


When declaring a new Symbol in a very wide source, instead of spoiling your time at compiling to get a double declaration error message, just Right-Click on the fresh written name. No move > OK.


Do not be afraid of giving your symbols very long, full talking names. The more expressive they are, the better it is for you, later, when maintaining your work. Full talking names are much better than end comments. They do not increase the compile time and save much of yours.


Because Multi-Files (Modular) programming is a very bad way to go (producing the same results and difficulties as C does), RosAsm compiles mono-files. This, too, may have some inconvenience when you want to reuse some chunks of code from one Application to another. So, you should never name a global Variable as, for example, ''W1'' and you should take the time to write a real full talking name; example: ''ThisWindowWidth'', so that, when pasting for reuse, the chances for naming conflicts become very low and the readability remains very high.


Same for Routines naming. Never calling any Routine ''Search:'', but, instead, ''SearchForTheNextLineInUserText:'', will save you from many future difficulties.



~~~~~~~




The Clip File



The Clip File  ...


The default Name of this File is 'Clip.txt', but you can name it whatever you like and specify it in the Configuration Tab.



Organization


The File is to be structured as a simple two level tree. The main level (Groups) is defined by lines like:


//Asm Snippets


//CallBacks


//Macros



The Sub-Level (Templates) are defined by lines like:


/Decimal To Binary


/String Length


/Upper Case



The Main Level items come in the left Dialog EditControl and the according Sub-Level, once a main level has been chosen, in the right EditControl. The Dialog, for showing the content of the Clip File does not do any control of the content organization. You have simply to write your Clips as you wish to get them coming up, in order and inside the desired main level.




The Customizing Feature


Any symbol beginning with a '@' will allow adding a generic name (in order to save rename typings). Example, if you write here a variable name as '@Length' and the [Clip] feature user enter 'My' in the Generic Name EditBox, the ClipBoard will contain 'MyLength' instead of '@Length'.


For sharing Clips, avoid using '§' and use the Dollar Char '$', instead. (This last one works on any KeyBoard/CharSet).


Of course, the logical of '@' working rules may be defeated in some cases, as it may serve two purposes (real Local symbols // Generic Names Flags), but, in most cases you will find it a friendly feature. Just write your Clips close enough to what you finally hope to retrieve.



Making Customization impossible


In some cases, for example, when storing ready to reuse Procedures (Proc), the customization of the Clip is not at all desireable. A direct copy will be done (and the Clip Dialog Radio-Buttons ignored), if the Clip begins with a leading '@' (second Line, first Row).



All of these Managements may be done through the The_Clip_Feature Dialog, available from the Main Menu.

~~~~~~~








Clip


Clip  ....



The [Clip] Menu option opens a Dialog for Sources Templates. Select a Template with the two List Boxes, click on the[OK] button: The Template is copied to the ClipBoard, ready to be pasted in your source.


In the right part of the Dialog, two flags can be set for Data on/off and for  Local/Global symbols. In most cases they should be of no use.


Down there, you will see an Edit Box for some 'Generic Name'. The so called 'Generic Name' is to be added at the beginning of all the Templates symbols, in order to save you from renaming.


Let us take an example. In RosAsm Data, there is a recorded Template for MessageBox api calls, which looks like this:


[@Title: '' '', 0

  @Message: '' '', 0]


  call 'USER32.MessageBoxA'  &NULL,  @Message,  @Title,  &MB_SYSTEMMODAL


If you set, for example the flags to ''Without Data'' and ''Global Scope'' and the Generic Name record to 'MyBase'', after you hit [OK], the ClipBoard will hold:


call 'USER32.MessageBoxA'  &NULL, MyBaseMessage, MyBaseTitle,&MB_SYSTEMMODAL



If you set the flags to ''With Data'' and ''Local Scope'', your ClipBoard will hold:


Local @Title, @Message


call 'USER32.MessageBoxA'  &NULL,  D@Message,  D@Title,  &MB_SYSTEMMODAL

As you may guess, if you load, for example, a Macros Set, the flags and Generic Name are not used.


You can edit the Clip file (The default file name is 'Clip.txt') with any text editor for modifications and  additions. If you have something that might be useful to others, do not forget to send it to me for re-distribution. 


In order to preserve your own choices from overwriting  when downloading a new RosAsm release, you can rename it, or save it in a particular folder. Run [Configuration] / [Files Locations] to define your new Path/Name.



Adding a Template


If you select a Block of Source before running the Clip Dialog, the [Add Template] Button is enabled. If you choose this Option, you are asked for the Name that will be added in the second ListBox list. If no Item is selected in this second ListBox, the Template is appended at the end of the Group. If an Item is selected, the next Template is inserted at that place.



Deleting a Template


As it says: Select a Template and it will be deleted if you answer [Yes] to the Message Box.



Groups Management


It is the same for [Add Group] [Del Group Name] [Del Group with Templates] . 'Add' offers you to either insert at the current selection (first ListBox) or to append, at the end of this first List.


~~~~~~~





The Reusing Choice


The Reusing Choice  ...



Each Assembler comes with its implied 'programming philosophy' and the one of RosAsm is in some way being  a 'Specific Assembler':


It is Specific in a way that it outputs only one type of file (I think its better having a tool doing properly only one thing than doing many things but, even if properly, always, at least, with much configuration and usage complications).


It is Specific, too, in that the way that it implies something I call a Specific-Programming-Style. What I mean exactly is a bit difficult to explain but it entirely stands in the expression... It is simpler to explain it as: 'opposed to Modular-Programming-Style'.


Modular programming in Assembler does not make much sense. If one wants to do modular programming, its better to use Basic. It does it perfectly. Now, the fact is that many programmers do not want to always re-invent the wheel, and want to easily reuse something , in some way, I.E. already written chunks of Code.


In the good old DOS time, Static Libraries were very useful to save one from seemingly endless Compilation times. Even today, with some Assemblers - Say, MASM, which is particularly slow - such a Code-Reuse Method may be of some interest. Given the actual performances of hardware, and given the Compilation speed of RosAsm, this Compilation times argument falls flat on its face.


In many other Assemblers, you still have LIBs and INCs, and this is, yet today, the HLL way, but, once Some code is saved as 'reusable'  this way, it becomes Black-Box. The bad thing with Black-Boxes is that you will forget what is inside, and, because reusing is easier than verifying what we are really doing, there are many chances that you will run inaccurate solutions to your programming problems.


An important point, with traditional Libraries, is that such an implementation would completely break down two of the most important features of RosAsm , that make the developments fast and easy: 1) Right-Click advanced Searches and the 2) Source Level [Run]-Time Debugging.


To make a Routine reusable, with these features, you have to make it hold all expected (and unexpected) possibilities. This is to say that you will run  big engines to solve tiny problems, in most circumstances.


Facing these problems, I have had to implement advanced Code-Reuse features in RosAsm, in order to make it a really up-to-date Development Tool.


The main way I have chosen, for reusing Code, is a feature called [Clip]. There is a 'Clips' File aside RosAsm that the user can edit, in which he can save his precious chunks of code and templates. Inside the Main Editor, there is a Menu option that runs a Clips Dialog allowing to choose / customize / Save in ClipBoard. Then, the user pastes it inside his source. Once done, he can adapt the pasted code to his real requirements. All of this is not much longer than LIBs and INCs techniques, but is far better from an Assembly point of view.


Another method, for the programmers who really want 'Libraries', is to consider the use of the TITLE feature (see Source_Editor [TITLE]), as an intermediate solution: We could as well call the TITLE saving, reloading, updating methods a kind of ''Source Level Library'' method. It is quite simple, to save the Library under the .asm from ([Ctrl] [S], and / or to save a ready to reuse Application with only the Base and the Library inside (a kind of extended 'BaseX.exe' File). At least, this intermediate solution will enable you with all the so useful features of Right-Click and with a direct pointing in error cases, if nothing else...


You will notice, too, that with LIBs and INCs techniques, the code Templates are often heavily optimized, in order to try to save with one hand, the time spoiled with the other hand. This way of doing things is then not only stupid, from a technical point of view, but, even worse, if you want to re-read the included chunks of code, you will have much more difficulties than with the simple strategy optimizing allowed by simple code pasting and adapting.


Another great thing with the [Clip] choice, compared to LIBs is that you do not have to memorize anything (what name, what parameters, what registers to preserve, and so on).


Let us consider two versions of a String length function. The first one is proposed in the Library of MASM32 package:


; ##########################################################################


    .386

    .model flat, stdcall

    option casemap :none   ; case sensitive


    .code


; ##########################################################################


StrLen proc item:DWORD


  ; -------------------------------------------------------------

  ; This procedure has been adapted from an algorithm written by

  ; Agner Fog. It has the unusual characteristic of reading up to

  ; three bytes past the end of the buffer as it uses DWORD size

  ; reads. It is measurably faster than a classic byte scanner on

  ; large linear reads and has its place where linear read speeds

  ; are important.

  ; -------------------------------------------------------------


    push    ebx

    mov     eax,item               ; get pointer to string

    lea     edx,[eax+3]            ; pointer+3 used in the end

  @@:     

    mov     ebx,[eax]              ; read first 4 bytes

    add     eax,4                  ; increment pointer

    lea     ecx,[ebx-01010101h]    ; subtract 1 from each byte

    not     ebx                    ; invert all bytes

    and     ecx,ebx                ; and these two

    and     ecx,80808080h    

    jz      @B                     ; no zero bytes, continue loop

    test    ecx,00008080h          ; test first two bytes

    jnz     @F

    shr     ecx,16                 ; not in the first 2 bytes

    add     eax,2

  @@:

    shl     cl,1                   ; use carry flag to avoid branch

    sbb     eax,edx                ; compute length

    pop     ebx


    ret


StrLen endp


; ##########################################################################


end



The Second one is the one I wrote in the default RosAsm Clips File:


mov edi StringPointer, ecx 0-1, al 0

repne scasb

mov eax 0-2 | sub eax ecx      ; Length in eax.



As you can see, the code of the include version is highly optimized. It applies the search upon dWords instead of bytes, and, so forth tends to run four times faster than my version, when parsing very long strings... if they are both structured and called in the same way.


Now, if you test these two routines on very short string, this will not be true. If you test upon middle length strings, the organization (simple code Lines vs independent Procedure) will make the speed difference visible or not. For very long chunks of text, in real life programming, we simply avoid, as long as possible to continuously call for such routines. The best strategy, anyway, is to manage two Variables: One for the length and one for the End_Of_Text all along text modifications.


So, the results of implementing such reusable black-boxes are:


Visual Basic tendencies in programming..

Less readable code.

Decrease of flexibility (what if you have to search for Carriage Return instead of zero?).

Making easy to use inaccurate Strategy solutions.

Loss of control. Example, both examples destroy ecx, but in my version, once pasted in your source, you just have it visible.

~~~~~~~


 





Reusing Code



Reusing Code . 




Reusing_Choice


The_Clip_Feature


Clip_File



Other features may be considered of interest for Sources reuse. See also the TITLE feature, in the Source_Editor chapter, and the IncIncluder_Parser Chapter.


~~~~~~~