EnglishРусский  

   ..

   arr.c

   arr.h

   arrdata.c

   arrdata.h

   buf.c

   buf.h

   crc.c

   crc.h

   file.c

   file.h

   hash.c

   hash.h

   memory.c

   memory.h

   mix.c

   mix.h

   msg.c

   msg.h

   msglist.c

   msglist.g

   msglist.h

   number.c

   number.h

   str.c

   str.h

   types.h

Реклама

Инсталлятор CreateInstall
Бесплатные и коммерческие инсталляторы

  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2006, The Gentee Group. All rights reserved. 
  4 * This file is part of the Gentee open source project - http://www.gentee.com. 
  5 * 
  6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT"). 
  7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS 
  8 * ACCEPTANCE OF THE AGREEMENT.
  9 *
 10 * ID: str 18.10.06 0.0.A.
 11 *
 12 * Author: Alexey Krivonogov
 13 *
 14 * Summary: This file provides functionality for 'str' type.
 15 *
 16 ******************************************************************************/
 17 
 18 #include "str.h"
 19 #include "../genteeapi/gentee.h"
 20 #include "../os/user/defines.h"
 21 
 22 /*-----------------------------------------------------------------------------
 23 * Id: str_opadd F4
 24 * 
 25 * Summary: Appending types to the string. Append #b(str) to #b(str) => 
 26            #b( str += str ).
 27 *  
 28 * Title: str += type
 29 *
 30 * Return: The result string.
 31 *
 32 * Define: operator str +=( str left, str right ) 
 33 *
 34 -----------------------------------------------------------------------------*/
 35 
 36 pstr  STDCALL str_add( pstr dest, pstr src )
 37 {
 38    dest->use--;
 39    return buf_add( dest, src );
 40 }
 41 
 42 /*-----------------------------------------------------------------------------
 43 * Id: str_opadd_1 FC
 44 * 
 45 * Summary: Append #b(uint) to #b(str) => #b( str += uint ).
 46 *  
 47 * Define: operator str +=( str left, uint right ) 
 48 *
 49 -----------------------------------------------------------------------------*/
 50 
 51 pstr   STDCALL str_appenduint( pstr ps, uint val )
 52 {
 53    return str_printf( ps, "%u", val );
 54 }
 55 
 56 /*-----------------------------------------------------------------------------
 57 * str_clear F3
 58 * 
 59 * Summary: Clear the string.
 60 *  
 61 * Return: #lng/retobj#
 62 *
 63 * Define: method str str.clear()  
 64 *
 65 -----------------------------------------------------------------------------*/
 66 
 67 pstr   STDCALL str_clear( pstr ps )
 68 {
 69    ps->use = 1;
 70    ps->data[0] = 0;
 71 
 72    return ps;
 73 }
 74 
 75 /*-----------------------------------------------------------------------------
 76 * Id: str_opeq F4
 77 * 
 78 * Summary: Copy the string.
 79 *  
 80 * Return: The result string.
 81 *
 82 * Define: operator str =( str left, str right ) 
 83 *
 84 -----------------------------------------------------------------------------*/
 85 
 86 pstr  STDCALL str_copy( pstr dest, pstr src )
 87 {
 88    return buf_copy( ( pbuf )dest, str_ptr( src ), src->use );
 89 }
 90 
 91 /*-----------------------------------------------------------------------------
 92 * Id: str_copy F2
 93 * 
 94 * Summary: Copying. The method copies data into a string.
 95 *  
 96 * Title: str.copy...
 97 *
 98 * Params: ptr - The pointer to the data being copied. All data to the zero /
 99                 character will be copied.
100 *
101 * Return: #lng/retobj#
102 *
103 * Define: method str str.copy( uint ptr ) 
104 *
105 -----------------------------------------------------------------------------*/
106 
107 pstr   STDCALL str_copyzero( pstr ps, pubyte src )
108 {
109    ps->use--;
110    buf_copyzero( ps, src );
111    return ps;
112 }
113 
114 /*-----------------------------------------------------------------------------
115 * Id: str_copy_1 FA
116 * 
117 * Summary: The method copies the specified size of the data into a string.
118 *  
119 * Params: ptr - The pointer to the data being copied. If data does not end in /
120                 a zero, it will be added automatically.
121           len - The size of the data being copied. 
122 *
123 * Return: #lng/retobj#
124 *
125 * Define: method str str.load( uint ptr, uint len ) 
126 *
127 -----------------------------------------------------------------------------*/
128 
129 pstr   STDCALL str_copylen( pstr ps, pubyte src, uint len )
130 {
131    ps->use--;
132 //   print("String Load %i %x\n", len, src );
133    buf_copy( ps, src, len );
134    return buf_appendch( ps, 0 );
135 }
136 
137 //--------------------------------------------------------------------------
138 
139 pstr STDCALL str_dirfile( pstr dir, pstr name, pstr ret )
140 {
141    str_copy( ret, dir );
142    str_trim( ret, SLASH, TRIM_ONE | TRIM_RIGHT );
143    return str_printf( ret, "%c%s", SLASH, str_ptr( name ));
144 }
145 
146 /*-----------------------------------------------------------------------------
147 * Id: str_substr F2
148 * 
149 * Summary: Getting a substring. 
150 *  
151 * Params: src - Initial string. 
152           off - Substring offset. 
153           len - Substring size. 
154 *
155 * Return: #lng/retobj#
156 *
157 * Define: method str str.substr( str src, uint off, uint len ) 
158 *
159 -----------------------------------------------------------------------------*/
160 
161 pstr STDCALL str_substr( pstr dest, pstr src, uint off, uint len )
162 {
163    uint slen = str_len( src );
164 
165    if ( len && off < slen )
166    {
167       if ( len > slen - off )
168          len = slen - off;
169       str_copylen( dest, str_ptr( src ) + off, len );
170    }
171    else 
172       str_clear( dest );
173 
174    return dest;
175 }
176 
177 #ifndef NOGENTEE
178 
179 /*-----------------------------------------------------------------------------
180 *
181 * ID: str_getdirfile 19.10.06 0.0.A.
182 * 
183 * Summary: Get directory and filename
184 *
185 -----------------------------------------------------------------------------*/
186 
187 uint STDCALL str_getdirfile( pstr src, pstr dir, pstr name )
188 {
189    uint   separ = str_find( src, 0, SLASH, 1 );
190    uint   off;
191 
192    off = separ >= str_len( src ) ? 0 : separ + 1;
193    
194    if ( name )
195       str_copyzero( name, str_ptr( src ) + off );
196    if ( dir )
197       str_substr( dir, src, 0, separ < str_len( src ) ? separ : 0 );
198    return 1;
199 }
200 
201 #endif // NOGENTEE
202 
203 pstr STDCALL str_init( pstr ps )
204 {
205    mem_zero( ps, sizeof( str ));
206    
207    buf_alloc( ps, 32 );
208    ps->data[0] = 0;
209    ps->use = 1;
210 //   print("String Init ps=%x len = %i data = %x ptr=%s\n", ps, ps->use, ps->data,
211 //          ps->data );
212    return ps;
213 }
214 
215 #ifndef NOGENTEE
216 
217 /*-----------------------------------------------------------------------------
218 * Id: str_find F2
219 * 
220 * Summary: Find the character in the string. 
221 *  
222 * Title: str.find...
223 *
224 * Params: offset - The offset to start searching from.
225           symbol - Search character.
226           fromend - If it equals 1, the search will be carried out from the /
227                     end of the string.
228 *
229 * Return: The offset of the character if it is found. If the character is not 
230           found, the length of the string is returned.
231 *
232 * Define: method uint str.findch( uint offset, uint symbol, uint fromend ) 
233 *
234 -----------------------------------------------------------------------------*/
235 
236 uint  STDCALL str_find( pstr ps, uint offset, ubyte symbol, uint fromend )
237 {
238    pubyte   cur = ps->data + offset;
239    pubyte   end = ps->data + str_len( ps ); 
240    pubyte   last;
241 
242    if ( _gentee.multib )
243    {
244       last = end;
245       while ( cur < end )
246       {
247          if ( os_isleadbyte( *cur ))
248             cur++;
249          else
250             if ( *cur == symbol )
251                if ( fromend )
252                   last = cur;
253                else
254                   break;
255          cur++;
256       }
257       if ( fromend )
258          cur = last;
259    }
260    else
261       if ( fromend )
262       {
263          cur = end;
264          while ( cur >= ps->data )
265          {
266             if ( *cur == symbol )
267                break;
268             cur--;
269          }
270          if ( cur < ps->data )
271             cur = end;
272       }
273       else
274       {
275          while ( cur < end )
276          {
277             if ( *cur == symbol )
278                break;
279             cur++;
280          }
281       }
282 
283    return ( cur < end ? cur - ps->data : str_len( ps ));
284 }
285 
286 /*-----------------------------------------------------------------------------
287 * Id: str_find_1 FA
288 * 
289 * Summary: Find the character from the beginning of the string. 
290 *  
291 * Params: symbol - Search character.
292 *
293 * Define: method uint str.findch( uint symbol ) 
294 *
295 -----------------------------------------------------------------------------*/
296 
297 uint  STDCALL str_findch( pstr ps, ubyte symbol )
298 {
299    return str_find( ps, 0, symbol, 0 );
300 }
301 
302 #endif
303 
304 /*-----------------------------------------------------------------------------
305 * Id: str_oplen F4
306 * 
307 * Summary: Get the length of a string.
308 *  
309 * Return: The length of the string.
310 *
311 * Define: operator uint *( str left ) 
312 *
313 -----------------------------------------------------------------------------*/
314 
315 uint  STDCALL str_len( pstr ps )
316 {
317    return ps->use - 1;
318 }
319 
320 /*-----------------------------------------------------------------------------
321 *
322 * ID: str_print 19.10.06 0.0.A.
323 * 
324 * Summary: Output wsprintf to str.
325 *  
326 -----------------------------------------------------------------------------*/
327 
328 pstr  CDECLCALL str_printf( pstr ps, pubyte output, ... ) 
329 {
330    va_list args;
331    uint    len = ps->use - 1;
332 
333    str_expand( ps, 512 );
334    va_start( args, output );
335    str_setlen( ps, len + vsprintf( ps->data + len, output, args ));
336    va_end( args );
337 
338    return ps;
339 }
340 
341 #ifndef NOGENTEE
342 
343 /*-----------------------------------------------------------------------------
344 * Id: str_printf F2
345 * 
346 * Summary: Write formatted data to a string. The method formats and stores a 
347            series of characters and values in string. Each argument is 
348            converted and output according to the corresponding C/C++ format 
349            specification (printf) in format parameter.
350 *  
351 * Params: format - The format of the output. 
352           clt - Optional arguments.
353 *
354 * Return: #lng/retobj#
355 *
356 * Define: method str str.printf( str format, collection clt ) 
357 *
358 -----------------------------------------------------------------------------*/
359 
360 pstr  STDCALL str_sprintf( pstr ps, pstr output, pcollect pclt ) 
361 {
362    uint  args[32];
363    uint  len = ps->use - 1;
364    uint  i, k = 0, itype;
365 
366    str_expand( ps, 1024 );
367    for ( i = 0; i < collect_count( pclt ); i++ )
368    {
369       itype = collect_gettype( pclt, i );
370       if ( itype == TDouble || itype == TLong || itype == TUlong )
371       {
372          args[k++] = *( puint )collect_index( pclt, i );
373          args[k++] = *(( puint )collect_index( pclt, i ) + 1 );
374       }
375       else
376       {
377          args[k++] = *( puint )collect_index( pclt, i );
378          if ( itype == TStr )
379             args[k - 1] = (uint)(( pstr )args[k - 1])->data;
380       }
381    }
382    str_setlen( ps, len + vsprintf( ps->data + len, output->data, (pubyte)args ));
383 
384    return ps;
385 }
386 
387 #endif // NOGENTEE
388 
389 /*-----------------------------------------------------------------------------
390 * Id: str_out4 F2
391 * 
392 * Summary: Output a 32-bit value. The value is appended at the end of the 
393            string.
394 *  
395 * Params: format - The format of the output. It is the same as in the function /
396                    'printf' in C programming language.
397           val - 32-bit value to be appended.
398 *
399 * Return: #lng/retobj#
400 *
401 * Define: method str str.out4( str format, uint val ) 
402 *
403 -----------------------------------------------------------------------------*/
404 
405 pstr  STDCALL str_out4( pstr ps, pstr format, uint val ) 
406 {
407    return str_printf( ps, str_ptr( format ), val );
408 }
409 
410 /*-----------------------------------------------------------------------------
411 * Id: str_out4_1 FA
412 * 
413 * Summary: Output a 64-bit value. The value is appended at the end of the 
414            string.
415 *  
416 * Params: format - The format of the output. It is the same as in the function /
417                    'printf' in C programming language.
418           val - 64-bit value to be appended.
419 *
420 * Return: #lng/retobj#
421 *
422 * Define: method str str.out8( str format, ulong val ) 
423 *
424 -----------------------------------------------------------------------------*/
425 
426 pstr  STDCALL str_out8( pstr ps, pstr format, ulong64 val ) 
427 {
428 //   print("Printf %x %s %I64u\n", ps, str_ptr(ps), format );
429 //   print("Printf %s\n", str_ptr( format ) );
430    return str_printf( ps, str_ptr( format ), val );
431 }
432 
433 #ifndef NOGENTEE
434 
435 /*-----------------------------------------------------------------------------
436 * Id: str_print F3
437 * 
438 * Summary: Print a string into the console window.
439 *  
440 * Define: method str.print() 
441 *
442 -----------------------------------------------------------------------------*/
443 
444 void  STDCALL str_output( pstr ps ) 
445 {
446    _gentee.print( str_ptr( ps ), str_len( ps ));
447 }
448 
449 #endif
450 
451 /*-----------------------------------------------------------------------------
452 * Id: str_print_1 F8
453 * 
454 * Summary: Print a string into the console window.
455 *
456 * Params: output - The output string.
457 *  
458 * Define: func print( str output ) 
459 *
460 -----------------------------------------------------------------------------*/
461 
462 /*-----------------------------------------------------------------------------
463 * Id: str_setlen F2
464 * 
465 * Summary: Setting a new string size. The method does not reserve space. 
466            You cannot specify the size of a string greater than the reserved 
467            space you have. Mostly, this function is used for specifying the 
468            size of a string after external functions write data to it.
469 *  
470 * Params: len - New string size. 
471 *
472 * Return: #lng/retobj#
473 *  
474 * Define: method str str.setlen( uint len ) 
475 *
476 -----------------------------------------------------------------------------*/
477 
478 pstr   STDCALL str_setlen( pstr ps, uint len )
479 {
480    if ( len >= ps->size )
481       len = 0;
482 
483    ps->use = len + 1;
484    ps->data[ len ] = 0;
485 
486    return ps;
487 }
488 
489 /*-----------------------------------------------------------------------------
490 *
491 * ID: str_trim 19.10.06 0.0.A.
492 * 
493 * Summary: Trim left and right characters
494 *  
495 * Params: 
496 *
497 -----------------------------------------------------------------------------*/
498 
499 pstr STDCALL str_trim( pstr ps, uint symbol, uint flag )
500 {
501    uint len = str_len( ps );
502 /*   uint rsymbol = symbol
503    
504    if flag & $TRIM_PAIR
505    {
506       switch symbol
507       {
508          case '(' : rsymbol = ')'
509          case '{' : rsymbol = '}'
510          case '[' : rsymbol = ']'
511          case '<' : rsymbol = '>'
512       }      
513    }*/
514    if  ( flag & TRIM_RIGHT )
515    {
516       uint i = len;
517 
518       while ( i && ps->data[ i - 1 ] == symbol )
519       {
520          i--;
521          if ( flag & TRIM_ONE )
522             break;
523       }
524       if ( i < len )
525          str_setlen( ps, i );
526    }
527 /*   if  flag & $TRIM_LEFT
528    {
529       uint   cur = this.ptr()
530       uint   end = cur + *this
531 
532       while cur < end && cur->byte == symbol
533       {
534          cur++
535          if flag & $TRIM_ONE : break
536       }
537       if cur != this.ptr() : this.del( 0, cur - this.ptr())
538    }
539 */
540    return ps;
541 }
542 
543 /*-----------------------------------------------------------------------------
544 *
545 * ID: str_new 19.10.06 0.0.A.
546 * 
547 * Summary: Create str object.
548 *  
549 -----------------------------------------------------------------------------*/
550 
551 pstr  STDCALL str_new( pubyte ptr )
552 {
553    pstr  ret = mem_alloc( sizeof( str ));
554 
555    str_init( ret );
556    if ( ptr )
557       str_copyzero( ret, ptr );
558 
559    return ret;
560 }
561 
562 /*-----------------------------------------------------------------------------
563 *
564 * ID: str_destroy 19.10.06 0.0.A.
565 * 
566 * Summary: Destroy str object.
567 *  
568 -----------------------------------------------------------------------------*/
569 
570 void  STDCALL str_destroy( pstr ps )
571 {
572    str_delete( ps );
573    mem_free( ps );
574 }
575 
576 /*-----------------------------------------------------------------------------
577 *
578 * ID: str_isequalign 19.10.06 0.0.A.
579 * 
580 * Summary: If two string equal.
581 *  
582 -----------------------------------------------------------------------------*/
583 
584 uint   STDCALL str_isequalign( pstr left, pstr right )
585 {
586    return left->use == right->use && 
587            !mem_cmpign( str_ptr( left ), str_ptr( right ), left->use );
588 }
589 
590 /*-----------------------------------------------------------------------------
591 *
592 * ID: str_pos2line 19.10.06 0.0.A.
593 * 
594 * Summary: Get the line from absolute position.
595 *  
596 -----------------------------------------------------------------------------*/
597 
598 uint  STDCALL str_pos2line( pstr ps, uint pos, puint lineoff )
599 {
600    uint    i, off = 0;
601    uint    line = 0;
602    pubyte  cur = str_ptr( ps );
603 
604    for ( i = 0; i < pos; i++ )
605    {
606       if ( cur[i] == 0xA )
607       {
608          line++;
609          off = i + 1;
610       }
611    }
612    if ( lineoff )
613       *lineoff = pos - off;
614    return line;
615 }
616 
617 //--------------------------------------------------------------------------
618 
619 uint  STDCALL ptr_wildcardignore( pubyte src, pubyte mask )
620 {
621    while ( 1 )
622    {
623       if ( !*src )
624          return ( !*mask || ( *mask == '*' && !*( mask + 1 ))) ? TRUE : FALSE; 
625       if ( !*mask )
626          break;
627       if ( os_lower( ( pubyte )*src ) == os_lower( ( pubyte )*mask ) ||
628                       *mask == '?' )
629       {
630          src++;
631          mask++;
632       }
633       else
634          if ( *mask == '*' )
635          {
636             if ( os_lower( ( pubyte )*src ) == os_lower( ( pubyte )*( mask + 1 )) &&
637                    ptr_wildcardignore( src, mask + 1 ))
638                return TRUE;
639             src++;
640          }
641          else
642             break;
643    }
644    return FALSE;
645 }
646 
647 #ifndef NOGENTEE
648 
649 /*-----------------------------------------------------------------------------
650 ** Id: str_fwildcard F2
651 *
652 * Summary: Wildcard check. Check if a string coincides with the specified mask.  
653 * 
654 * Params: wildcard - The mask being checked. It can contain '?' (one character) /
655                      and '*' (any number of characters).  
656 *
657 * Return: Returns 1 if the string coincides with the mask.
658 *
659 * Define: method uint str.fwildcard( str wildcard )
660 *
661 -----------------------------------------------------------------------------*/
662 
663 uint   STDCALL str_fwildcard( pstr name, pstr mask )
664 {
665    uint   ret;
666    uint   dotstr;
667    uint   dotmask;
668    pubyte pname = str_ptr( name );
669    pubyte pmask = str_ptr( mask );
670    uint   isstr = FALSE;
671    uint   ismask = FALSE;
672    uint   empty = 0;
673 
674    dotstr = str_find( name, 0, '.', TRUE );
675    dotmask = str_find( mask, 0, '.', TRUE );
676 
677    if ( pname[ dotstr ] )
678    {
679       pname[ dotstr ] = 0;
680       isstr = TRUE;
681    }
682    if ( pmask[ dotmask ] )
683    {
684       pmask[ dotmask ] = 0;
685       ismask = TRUE;
686    }
687    ret = ptr_wildcardignore( pname, pmask );
688    if ( ismask || ( isstr && pmask[ dotmask - 1 ] != '*' ))
689       ret &= ptr_wildcardignore( isstr ? pname + dotstr + 1 : ( pubyte )&empty,
690                               ismask ? pmask + dotmask + 1 : ( pubyte )&empty );
691    if ( isstr )
692       pname[ dotstr ] = '.';
693    if ( ismask )
694       pmask[ dotmask ] = '.';
695    return ret;
696 }
697 
698 #endif
699 //--------------------------------------------------------------------------
700 
Редактировать