Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ;
  2. ;  String helpers
  3. ;
  4. ;  (C) KolibriOS team (parts from another project)
  5. ;  (C) 2022 Coldy (str_buld function)  
  6. ;  Thank's you for use this code and software based on it!
  7. ;  I will glad if it's will be helpful.
  8. ;
  9. ;  Distributed under terms of GPL
  10. ;
  11.  
  12. ;****************************************
  13. ;*  input:  esi = pointer to string     *
  14. ;*  output: ecx = length of the string  *
  15. ;****************************************
  16. strlen:
  17.       push      eax esi
  18.       xor       ecx, ecx
  19.       @@:
  20.         lodsb
  21.         or      al, al
  22.         jz      @f
  23.         inc     ecx
  24.         jmp     @b
  25.       @@:
  26.       pop      esi eax
  27.   ret
  28.  
  29. ;*************************************************
  30. ;*  input:  esi = pointer to the src string      *
  31. ;*          edi = pointer to the dest string     *
  32. ;*          ecx = number of bytes to copy        *
  33. ;*************************************************
  34. strncpy:
  35.       push      eax ecx esi edi
  36.       @@:
  37.         lodsb
  38.         stosb
  39.         or      al, al
  40.         jz      @f
  41.         dec     ecx
  42.         jz      @f
  43.         jmp     @b
  44.       @@:
  45.       pop       edi esi ecx eax
  46.   ret
  47.  
  48. if 0 ; { Not used  
  49.  
  50. ;*************************************************
  51. ;*  input:  esi = pointer to the src string      *
  52. ;*          edi = pointer to the dest string     *
  53. ;*************************************************
  54. strcpy:
  55.      push  esi edi
  56.      ; ecx = ???
  57.      ; ZF = 0
  58.      rep   movsb
  59.      pop   edi esi
  60.   ret
  61.  
  62. ;*************************************************
  63. ;*  input:  esi = pointer to the src string      *
  64. ;*          edi = pointer to the dest string     *
  65. ;*          ecx = number of bytes to copy        *
  66. ;*************************************************
  67. strncat:
  68.      push  edi
  69.      push  ecx esi
  70.      mov   esi, edi
  71.      call  strlen
  72.      add   edi, ecx
  73.      pop   esi ecx
  74.      call  strncpy
  75.      pop   edi
  76.   ret
  77.  
  78. ;*************************************************
  79. ;*  (c) Coldy 2022                               *
  80. ;*  input:  edi = pointer to the dest string     *
  81. ;*          ecx = number of bytes to zero        *
  82. ;*************************************************
  83. ;memnz:
  84. ;     push  eax ecx edi
  85. ;     xor   eax, eax
  86. ;     rep   stosb
  87. ;     pop   edi ecx eax
  88. ;  ret
  89.  
  90. end if ; }
  91.  
  92. ;
  93. ; str_build
  94. ;
  95. ; Purose:       Build output string by template. Allocate necessary output
  96. ;               buffer, copy parts from template and insert strings instead
  97. ;               of $ wildcard.
  98. ;              
  99. ;               SPECIAL CASE:
  100. ;               For use dollar sing ($) in text, just mark this plase(s) in
  101. ;               template and provide pointer(s) on string with this sign in args)
  102. ;
  103. ;               PRECAUTION:
  104. ;            1. Not safe, caller must provide args count >= $ wildcard count
  105. ;            2. If used dynamic memory allocator then caller must free output
  106. ;               buffer
  107. ;            3. Looks like cdecl, but she is not. For cdecl need compat wrapper
  108. ;            4. Dirties all registers, incl. ebp
  109. ;
  110. ; Input:
  111. ;       esp+4 = pointer to template string
  112. ;       esp+8 = wildcard strings pointers in reverse order
  113. ;
  114. ; Options:
  115. if ~STR_BUILD_OFFSET
  116. STR_BUILD_OFFSET = 0
  117. ;               Optional, specify STR_BUILD_OFFSET value for offset from start
  118. ;               of output buffer (this useful for postinsert initial characters
  119. ;               before output sting). By default - no offset (0)
  120. end if
  121. if ~STR_BUILD_EXTRA
  122. STR_BUILD_EXTRA = 0
  123. ;               Optional, specify STR_BUILD_EXTRA value for extra length of
  124. ;               output bufer (this useful for postadding characters after
  125. ;               output string). By default - no extra length (0)
  126. end if
  127.  
  128. ;
  129. ; { STR_BUILD_NO_DOLLAR_SIGN - should be removed, see cpecial case above }
  130.  
  131. ;
  132. ;              Next two options below can reduse total code size by exclude
  133. ;              corresponding parts if they are not used
  134. ;
  135. if ~STR_BUILD_NO_STARTING_TEXT
  136. STR_BUILD_NO_STARTING_TEXT  = 0
  137. ;              Specify STR_BUILD_NO_STARTING_TEXT if you do not used templates
  138. ;              starting with text, e.g."Some text first $, $"
  139. ;              By default is disabled (0)
  140. end if
  141. ;
  142. if ~STR_BUILD_NO_DOUBLE_WILDCARD
  143. STR_BUILD_NO_DOUBLE_WILDCARD  = 0
  144. ;              Specify STR_BUILD_NO_DOUBLE_WILDCARD if you not used templates
  145. ;              with double wildcards, e.g. "$$ some text" or "Some text $$"
  146. ;              By default is disabled (0)
  147. end if
  148. ;
  149. ;   mem_alloc(size)
  150. ;               external memory allocator, stdcall. Must return pointer (in eax)
  151. ;               to base of memory block by size length. By defauld used internal
  152. ;
  153. ; Output:
  154. ;         eax = Pointer to output string (see PRECAUTION #2) or 0 if error
  155. ;         edi = Cursor of output string. No mean inf if eax = 0    
  156. ;
  157. ; Stack struct
  158. ;         ------
  159. ;        | ArgN  |
  160. ;         -------
  161. ;        |  ...  |
  162. ;         -------
  163. ;  ebp+4 | Arg1  |
  164. ;  ------ -------
  165. ;  ebp   | TplS  |  Template string
  166. ;  ------ -------
  167. ;        | ret   |  Caller return address (not used), esp when entry
  168. ;         -------
  169. ;        | $off1 |  1st offset in template string
  170. ;         -------
  171. ;        |  ...  |
  172. ;         -------
  173. ;        | $offN |  N-offset in template string
  174. ;         -------
  175. ;        | EOTpl |  End of template string, esp after phase 1.1
  176. ;         -------
  177. ;        | Len1  |  Length of 1st wildcard string  
  178. ;         -------
  179. ;        |  ...  |
  180. ;         -------
  181. ;        | LenN  |  Length of N wildcard string, esp after phase 1.2  
  182. ;         -------
  183. ;
  184. str_build:
  185.      mov  ebp, esp        ; Store caller esp...
  186.      add  ebp, 8          ; ... and shift return address and tamplate string
  187.      mov  esi, [ebp-4]  
  188.      xor        edx, edx        ; Offsets, length...
  189.      xor        edi, edi        ; Found count...
  190.      
  191.      ; Phase 1.1. Scan to find positions $ and store to stack offsets $+1
  192.      ; and end of template string. Break scan if zero byte appear
  193. .scan:
  194.      lodsb
  195.      inc        edx
  196.      or al, al
  197.      jz .end_scan
  198.      cmp  al, '$'
  199.      je .found
  200.      jmp        .scan
  201. .found:  
  202.      push   edx           ; Store offset
  203.      inc    edi
  204.      jmp    .scan
  205. .end_scan:
  206.     or      edi, edi
  207.     jz      .error        ; Not found
  208.     push    edx           ; Store last offset (end of template string)
  209.     sub     edx, edi      
  210.     dec     edx           ; Total length + zero string            
  211.    
  212.     ; Phase 1.2. Store to stack lengths of wildcard strings
  213.     mov    eax, edi
  214. @@:
  215.     mov    esi,[ebp+4*(eax-1)]
  216.     call   strlen
  217.     add    edx, ecx
  218.     push   ecx
  219.     dec    eax
  220.     inc    edi                      ; once edi*2 instead
  221.     test   eax,eax
  222.     jnz    @b
  223.    
  224.     add     edx, STR_BUILD_OFFSET + STR_BUILD_EXTRA  
  225.    
  226.     ; Phase 1.3. Allocate buffer for output string
  227. if defined mem_alloc
  228.     stdcall mem_alloc, edx
  229. else
  230.     mov    eax, 68
  231.     mov    ebx, 12
  232.     mov    ecx, edx
  233.     int    0x40
  234. end if
  235.     test   eax,eax
  236.     jz     .exit
  237.    
  238.     mov    byte[eax+edx],0          ; Mark end of output string
  239.    
  240.     ; Phase 2. Build output string
  241.    
  242.                                     ; eax = base of output string
  243.     xor    ebx, ebx                 ; ebx = index of args data
  244.                                     ; ecx = free, but used below
  245.     mov   edx, edi                  ; edx = index of stored data
  246.                                     ; esi = free, but used below
  247.     mov   edi, eax                  ; edi = cursor of output string
  248.    
  249.     add   edi, STR_BUILD_OFFSET
  250. if ~STR_BUILD_NO_STARTING_TEXT ; {    
  251.     mov   ecx, [esp+4*edx]          ; Offset
  252.     cmp   ecx,1                     ; Wildcard first?
  253.     je    .build
  254.  
  255.     mov   esi, -2                   ; One or double wildcard at the end
  256.     neg   ecx
  257.     add   ecx, [esp+4*edx-4]        ; Next offset
  258.     cmp   ecx, 1                    ; More one wildcard at the end?
  259.     je    @f
  260.     dec  esi                        
  261.        
  262. @@:
  263.     mov   ecx,esi
  264.     add   ecx,[esp+4*edx-4]         ; Next offset
  265.     mov   esi,[ebp-4]               ; Template string
  266.     call   strncpy
  267.     add    edi, ecx                 ; Advance cursor
  268. end if; } STR_BUILD_NO_STARTING_TEXT    
  269. .build:
  270.     mov   esi, [ebp+4*ebx]          ; Wildcard string
  271.     mov   ecx,[esp+4*ebx]           ; Length
  272.     call   strncpy
  273.     add    edi, ecx                 ; Advance cursor
  274.     mov   ecx, [esp+4*edx]          ; Offset      
  275.  
  276.     mov   esi,[ebp-4]               ; Template string
  277.     add   esi, ecx
  278.     cmp  byte [esi], 0              ; End of string?
  279.     je    .exit
  280. if ~STR_BUILD_NO_DOUBLE_WILDCARD ; {  
  281.     cmp  byte [esi], '$'      
  282.     je   @f
  283. end if; } STR_BUILD_NO_DOUBLE_WILDCARD
  284.     neg   ecx
  285.     add   ecx,[esp+4*edx-4]         ; Next offset
  286.     dec   ecx
  287.     call   strncpy
  288.     add    edi, ecx                 ; Advance cursor
  289. @@: ; {  STR_BUILD_NO_DOUBLE_WILDCARD }  
  290.     inc ebx
  291.     dec edx
  292.     cmp ebx, edx
  293.     jne .build
  294. .exit:
  295.     ; Restore stack
  296.     sub   ebp, 8
  297.     mov   esp,ebp        
  298.     ret
  299.    
  300. .error:
  301.     xor   eax, eax
  302.     ret    
  303.  
  304.