source: golgotha/src/i4/string/string.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 20.3 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include <stdarg.h>
10#include <math.h>
11#include "string/string.hh"
12#include "file/file.hh"
13#include "memory/malloc.hh"
14#include "arch.hh"
15#include "error/error.hh"
16#include "memory/lalloc.hh"
17#include "memory/growheap.hh"
18
19i4_string_manager_class i4_string_man;
20
21i4_string_manager_class::node::node_allocator *i4_string_manager_class::node::nodes=0;
22w32 i4_string_manager_class::node::nodes_ref=0;        // number of string managers using 'nodes'
23
24i4_string_manager_class::array_node::node_allocator *i4_string_manager_class::array_node::nodes=0;
25
26static i4_const_str *null_string;
27
28////////////////////////////////////////////////////////////////////////
29//
30//  Constant String Methods
31//
32
33i4_str::~i4_str()
34{
35  if (ptr)
36    i4_free((char *)ptr);
37}
38
39
40
41#ifndef i4_NEW_CHECK
42void *i4_string_manager_class::node::operator new(size_t size)
43{
44  return nodes->alloc();
45}
46
47void i4_string_manager_class::node::operator delete(void *ptr)
48{
49  nodes->free((node *)ptr);
50}
51#endif
52
53
54i4_string_manager_class::node::~node()
55{
56  if (left)
57    delete left;
58
59  if (right)
60    delete right;
61}
62
63
64#ifndef i4_NEW_CHECK
65void *i4_string_manager_class::array_node::operator new(size_t size)
66{
67  return nodes->alloc();
68}
69
70void i4_string_manager_class::array_node::operator delete(void *ptr)
71{
72  nodes->free((array_node *)ptr);
73}
74#endif
75
76
77i4_string_manager_class::array_node::~array_node()
78{
79  if (left)
80    delete left;
81
82  if (right)
83    delete right;
84}
85
86i4_const_str::iterator i4_const_str::strstr(const i4_const_str &needle_to_find) const
87{
88  iterator j=needle_to_find.begin();
89  for (iterator i=begin(); i!=end(); ++i)
90  {
91    iterator k=i;
92    j=needle_to_find.begin();
93    while (j.get()==k.get())
94    {
95      ++j;
96      if (j==needle_to_find.end())
97        return i;
98      ++k;
99    }
100  }
101  return end();     
102}
103
104i4_str *i4_const_str::vsprintf(w32 max_length, va_list &ap) const
105{
106  i4_str *ns=new i4_str(*this,max_length);
107  char *fmt=ptr,*out=ns->ptr;
108  int l=length();
109
110  while (*fmt && l)
111  {
112    if (*fmt=='%')
113    {
114      fmt++;
115      if (*fmt=='S')
116      {
117        l--;
118        i4_const_str *cs=va_arg(ap, i4_const_str *);
119        if (cs)
120        {
121          i4_const_str::iterator it=cs->begin();
122          while (it!=cs->end())
123          {
124            *out=(char)it.get().value();
125            out++;
126            ++it;
127          }
128        }
129      } else
130      {
131        char fmt_str[10],*fs;
132        fs=fmt_str+1;
133        fmt_str[0]='%';
134        do
135        {
136          *fs=*fmt;
137          fs++;       
138          fmt++;
139          l--;
140        } while (fmt[-1]!='s' &&
141                 fmt[-1]!='d' &&
142                 fmt[-1]!='f' &&
143                 fmt[-1]!='p' &&
144                 fmt[-1]!='g' &&
145                 fmt[-1]!='c' &&
146                 fmt[-1]!='i' &&
147                 fmt[-1]!='x' &&
148                 fmt[-1]!='u' &&
149                 fmt[-1]!='X' &&
150                 fmt[-1]!='o');
151        fmt--;
152        *fs=0;
153       
154        switch (*fmt)
155        {
156          case 'd' :
157          case 'i' :
158          case 'x' :
159          case 'X' :
160          case 'o' :
161            ::sprintf(out,fmt_str,va_arg(ap,int));
162            break;
163          case 'f' :
164          {
165            float f=va_arg(ap, double);
166            ::sprintf(out,fmt_str,f);
167          } break;
168          case 'g' :
169            ::sprintf(out,fmt_str,va_arg(ap,double));
170            break;
171          default :
172            ::sprintf(out,fmt_str,va_arg(ap,void *));
173            break;
174        }
175        while (*out)
176          out++;
177      }
178     
179    } else
180    {
181      *out=*fmt;
182      out++;
183    }
184    fmt++;
185    l--;
186  }
187  *out=0;
188
189  ns->len=strlen(ns->ptr);
190  return ns;
191}
192
193i4_str *i4_const_str::sprintf(w32 max_length, ...) const
194{
195
196
197  va_list ap;
198  va_start(ap, max_length);
199
200  i4_str *ret=vsprintf(max_length,ap);
201
202  va_end(ap);
203
204  return ret;
205}
206
207
208w32 i4_const_str::iterator::read_ascii(char *buffer, w32 buffer_size)
209{
210  w32 count=0;
211  iterator cur(*this);
212
213  while (cur.get().is_space())
214  {
215    ++cur;
216    ++node;
217  }
218
219  while (buffer_size>0 && cur.get().value() && !cur.get().is_space())
220  {
221    *(buffer++)=cur.get().value();
222    buffer_size--;
223    ++cur;   
224    ++node;
225    ++count;
226  }
227  *buffer=0;
228  return count;
229}
230
231
232i4_str *i4_const_str::iterator::read_string()
233{
234  iterator start(*this);
235
236  while (start.get().value() && start.get().is_space())
237  {
238    ++start;
239    ++node;
240  }
241
242  if (!start.get().value())
243    return 0;
244
245  w32 len=0;
246  iterator cur(start);
247
248  while (cur.get().value() && !cur.get().is_space())
249  {
250    ++len;
251    ++cur;
252    ++node;
253  }
254
255  i4_str *ret=new i4_str(start,cur,len+1);
256  return ret;
257}
258
259
260sw32 i4_const_str::iterator::read_number()
261{
262  iterator cur(*this);
263  while (cur.get().is_space())
264  {
265    ++cur;
266    ++node;
267  }
268
269  sw32 x=0;
270  i4_bool error=i4_F;
271
272  i4_bool neg;
273  if (cur.get() == i4_char('-'))
274  {
275    neg=i4_T;
276    ++cur;
277    ++node;
278  }
279  else neg=i4_F;
280
281
282  while (cur.get().value() && !cur.get().is_space() && !error)
283  {
284    char_type c=cur.get().value();
285    if (c<'0' || c>'9')
286      error=i4_T;
287    else
288    {
289      x=(x*10)+c-'0';
290     
291      ++node;
292      ++cur;
293    }
294  }
295
296  if (neg)
297    x=-x;
298
299  if (error)
300    return  0;
301  else return x;
302}
303
304
305double i4_const_str::iterator::read_float()
306{
307  while (get().is_space())
308    ++(*this);
309
310  double x=0;
311  sw32 exp=0;
312
313  i4_bool
314    error=i4_F;
315
316  i4_bool neg = i4_F;
317  if (get() == i4_char('-'))
318  {
319    neg=i4_T;
320    ++(*this);
321  }
322  else if (get() == i4_char('+'))
323    ++(*this);
324
325  while (get().value())
326  {
327    if (get()<i4_char('0') || get()>i4_char('9'))
328      break;
329
330    x = (x*10) + (double)(get().value()-'0');
331
332    ++(*this);
333  }
334
335  if (get() == i4_char('.'))
336  {
337    ++(*this);
338    while (get().value())
339    {
340      if (get()<i4_char('0') || get()>i4_char('9'))
341        break;
342     
343      x = (x*10) + (double)(get().value()-'0');
344      exp--;
345     
346      ++(*this);
347    }
348  }
349
350  if (get() == i4_char('e') || get() == i4_char('E'))
351  {
352    ++(*this);
353    exp += read_number();
354  }
355
356  if (neg)
357    x=-x;
358
359  if (error)
360    return  0;
361
362  return x*pow(10,exp);
363}
364
365
366////////////////////////////////////////////////////////////////////////
367//
368//  String methods
369//
370
371void i4_str::alloc(w16 _buf_len)
372{
373  buf_len = _buf_len;
374  if (buf_len==0)
375    ptr=0;
376  else
377    ptr=(char_type *)i4_malloc(sizeof(char_type)*(buf_len+1),"i4_str");
378}
379
380
381void i4_str::init_from_string(const i4_const_str &str, w16 _buf_len)
382{
383  if (!_buf_len)
384  {
385    ptr=0;
386    return ;
387  }
388
389  alloc(_buf_len);
390
391  len = (str.length() >= buf_len) ? buf_len : str.length();
392
393  i4_const_str::iterator p=str.begin();
394  char_type *c=ptr;
395
396  for (w16 x=0 ;x<len; ++x)
397  {
398    *c = (char_type)( p.get().value() );
399   
400    ++p;
401    ++c;
402  }
403  *c=0;
404}
405
406
407i4_str::i4_str(const i4_const_str::iterator start,
408               const i4_const_str::iterator last, w16 _buf_len)
409  : i4_const_str(0)
410{
411  alloc(_buf_len);
412
413  len=0;
414
415  char_type *c=ptr;
416  w16 count=buf_len;
417  i4_const_str::iterator s(start);
418
419  while (s!=last && count)
420  {
421    *c=(char_type)( s.get().value() );
422    ++c;
423    ++s;
424    ++len;
425    count--;
426  }
427  *c=0;
428}
429
430
431void i4_str::insert(i4_str::iterator p, const i4_char ch)
432//  insert ch before p
433{
434  if (len+1<buf_len)
435  {
436    if (p==end())
437    {
438      p.set(ch);
439      ++p;
440      p.set(0);
441      ++len;
442    }
443    else
444    {   
445      iterator c(ptr+len+1);
446      *c.node=0;
447      while (c!=p)
448      {
449        iterator q(c);
450        --c;
451        q.set(c.get());
452        --q;       
453      }
454      c.set(ch);
455      ++len;
456    }
457  }
458}
459
460
461void i4_str::insert(i4_str::iterator p, const i4_const_str &other)
462// insert other before p
463{
464  sw16 move_length=ptr_diff(p,end());
465  sw16 max_move=buf_len-(ptr_diff(begin(),p)+other.length()+1);
466
467  if (max_move>0)  // see if anything can be moved
468  {
469    iterator p2(0);
470    if (move_length>max_move)
471    {
472      move_length=max_move;
473      p2=iterator(ptr+buf_len-1);
474      len=buf_len-1;
475    } else
476    {
477      p2=iterator(ptr+ptr_diff(begin(),p)+other.length()+move_length);
478      len+=other.length();
479    }
480
481    p2.set(0);
482    --p2;
483     
484    i4_const_str::iterator p1(p);
485    for (w16 x=1;x<move_length;++x) ++p1;     
486
487    while (move_length)
488    {
489      p2.set(p1.get());
490      --p2;
491      --p1;
492      move_length--;
493    }
494
495  } else
496  {
497    len=buf_len-1;
498    ptr[buf_len-1]=0;
499  }
500     
501
502  // now see how much we can insert
503  sw16 insert_len=other.length();
504  if (insert_len+ptr_diff(begin(),p)>=buf_len)
505    insert_len=buf_len-ptr_diff(begin(),p)-1;
506
507  if (insert_len>0)
508  {
509    i4_const_str::iterator ip=other.begin();
510    while (insert_len)
511    {
512      p.set(ip.get());
513      ++p;
514      ++ip;
515      insert_len--;
516    }
517  }
518}
519
520
521void i4_str::remove(i4_str::iterator start, i4_str::iterator last)
522{
523  sw32 rm_len=ptr_diff(last,end()); 
524
525  len-=ptr_diff(start,last);
526
527  while (rm_len>0)
528  {
529    start.set(last.get());
530    ++start;
531    ++last;
532    rm_len--;
533  }
534
535  start.set(i4_char(0));
536}
537
538
539void i4_str::to_lower()
540{
541  for (i4_str::iterator p=begin(); p!=end(); ++p)
542    p.set(p.get().to_lower());
543}
544
545
546void i4_str::to_upper()
547{
548  for (i4_str::iterator p=begin(); p!=end(); ++p)
549    p.set(p.get().to_upper());
550}
551
552
553////////////////////////////////////////////////////////////////////////
554//
555// String Manager Methods
556//
557
558const i4_const_str &i4_string_manager_class::get(const char *internal_name)
559{
560  if (!internal_name)
561    return *null_string;
562
563  node *n=root;
564  while (n)
565  {
566    int c=strcmp(internal_name,n->str_token);
567    if (c<0)
568      n=n->left;
569    else if (c>0)
570      n=n->right;
571    else return n->value;
572  }
573  i4_warning("symbol not found %s\n",internal_name);
574
575  return *null_string;
576}
577
578void i4_string_manager_class::show_node(node *who)
579{
580  if (who)
581  {   
582    show_node(who->left);
583    i4_warning("%s\n",who->str_token);
584    show_node(who->right);
585  }
586}
587
588void i4_string_manager_class::show_nodes()
589{
590  if (root)
591    show_node(root);
592}
593
594i4_const_str *i4_string_manager_class::get_array(const char *internal_name)
595{
596  array_node *n=array_root;
597  while (n)
598  {
599    int c=strcmp(internal_name,n->str_token);
600    if (c<0)
601      n=n->left;
602    else if (c>0)
603      n=n->right;
604    else
605    {
606      w32 count=0,x;
607      char **c=n->value;
608      i4_const_str *ret;
609
610      while (*c)
611      {
612        c++;
613        count++;
614      }
615      ret=(i4_const_str *)i4_malloc(sizeof(i4_const_str)*(count+1),"array list");
616      for (x=0; x<count; x++)
617      {
618        ret[x].ptr=n->value[x];
619        ret[x].len=strlen(ret[x].ptr);
620      }
621      ret[count].ptr=0;
622      ret[count].len=0;
623
624      return ret;
625    }
626  }
627
628  i4_error("array not found %s\n",internal_name);
629  return 0;
630}
631
632
633void i4_string_manager_class::init()
634{
635  string_heap=new i4_grow_heap_class(0x1000,0x1000);
636
637  if (!node::nodes)
638  {
639    node::nodes=new i4_linear_allocator(sizeof(node),0,128,"strings");
640    array_node::nodes=new i4_linear_allocator(sizeof(array_node),
641                                              0,128,"arrays");
642    null_string=new i4_const_str(0);
643  }
644  i4_string_manager_class::node::nodes_ref++;
645
646
647  root=0;
648  array_root=0;
649}
650
651i4_string_manager_class::~i4_string_manager_class()
652{
653  if (string_heap)
654    delete string_heap;
655}
656
657void i4_string_manager_class::uninit()
658{
659  if (root)
660  {
661    delete_node(root);
662    root=0;
663  }
664  if (array_root)
665  {
666    delete_array_node(array_root);
667    array_root=0;
668  }
669
670  if (string_heap)
671  {
672    delete string_heap;
673    string_heap=0;
674  }
675
676  i4_string_manager_class::node::nodes_ref--;
677  if (i4_string_manager_class::node::nodes_ref==0)
678  {
679    delete node::nodes;           // if there are multiple string managers we can only do this
680    delete array_node::nodes;     // once, so for now we won't do it
681    node::nodes=0;
682    delete null_string;
683    null_string=0;
684  }
685}
686
687
688
689i4_string_manager_class::i4_string_manager_class()
690{
691  root=0;
692  array_root=0;
693  string_heap=0;
694}
695
696
697
698inline i4_bool space_char(char ch)
699{
700  return (i4_bool)(ch==' ' || ch=='\n' || ch=='\t' || ch=='\r');
701}
702
703
704
705char  *i4_string_manager_class::alloc_str(char *string)
706{
707  w16 len=strlen(string)+1;
708  void *storage=string_heap->malloc(len,"string");
709  memcpy(storage,string,len);
710  return (char *)storage;
711}
712
713
714
715void i4_string_manager_class::add_node(char *token, char *string)
716{
717  node **p=&root;
718  while (*p)
719  {
720    if (strcmp(token,(*p)->str_token)<0)
721      p=&(*p)->left;
722    else
723      p=&(*p)->right;
724  }
725  *p=new_node(alloc_str(token),i4_const_str(alloc_str(string)));
726}
727
728
729
730void i4_string_manager_class::add_array_node(char *token, char **array, w32 total)
731{
732  array_node **p=&array_root;
733  while (*p)
734  {
735    if (strcmp(token,(*p)->str_token)<0)
736      p=&(*p)->left;
737    else
738      p=&(*p)->right;
739  }
740
741  char **new_array;
742  new_array = (char**)ALIGN_FORWARD( string_heap->malloc((total+1)*sizeof(char*) + sizeof(int) - 1,
743                                                        "string_array") );
744  for (int i=0; i<total; i++)
745    new_array[i]=array[i];
746
747  new_array[total] = 0;
748
749  *p=new_array_node(alloc_str(token),new_array);
750}
751
752
753
754static void skip_white(char *&s, w32 &line_on)
755{
756  char *sl=s;   // use local pointer so a register can be substituted
757  while (1)
758  {
759    switch (*sl)
760    {
761      case ' ' :
762      case '\t' :
763      case '\r' :
764        sl++;
765        break;
766      case '\n' :
767        sl++;
768        line_on++;
769        break;
770      case '/' :
771      {
772        if (sl[1]=='/')
773        {
774          while (*sl && *sl!='\n' && *sl!='\r')
775            sl++;         
776        } else
777        {
778          s=sl;
779          return ;
780        }
781
782      } break;
783      default :
784        s=sl;
785        return;
786    }
787  }
788}
789
790static void *dump_file_buf;
791static int dump_buf_len;
792
793void i4_string_manager_class::expand_macro(char *&s, char *&buf, w32 &line_on, char *error_prefix)
794{
795  char *sl=s+1,*start;
796  w32 len;
797
798  skip_white(sl,line_on);
799  if (*sl!='{')
800  {
801    i4_file_class *fp=i4_open("dump.txt", I4_WRITE);
802    fp->write(dump_file_buf, dump_buf_len);
803    delete fp;
804    i4_error("%s:%d:expected { after $",error_prefix,line_on);
805  }
806
807  sl++;
808  start=buf;
809  get_token(sl,start,line_on,error_prefix);
810  *start=0;
811 
812  i4_const_str str=get(buf);
813  if (str.null())
814    i4_error("%s:%d: macro symbol has no value '%s'",error_prefix, line_on, buf);
815 
816  start=str.ptr;
817  len=str.length();
818  while (len)
819  {
820    len--;
821    *buf=*start;
822    start++;
823    buf++;
824  }
825   
826  skip_white(sl,line_on);
827  if (*sl!='}')
828    i4_error("%s:%d: expected }",error_prefix,line_on);   
829  sl++;
830  s=sl;
831}
832
833
834void i4_string_manager_class::get_char(char *&s, char *&buf, w32 &line_on, char *error_prefix)
835{
836  if (*s=='$')
837    expand_macro(s,buf,line_on,error_prefix);
838  else if (*s=='\\')
839  {
840    s++;
841    if (*s=='n') *buf='\n';
842    else if (*s=='r') *buf='\r';
843    else if (*s=='t') *buf='\t';
844    else *buf=*s;
845    s++;
846    buf++;
847  }
848  else
849  {
850    if (*s=='\n')
851      line_on++;
852    *buf=*s;
853    buf++;
854    s++;
855  } 
856}
857
858
859
860void i4_string_manager_class::read_array(char *&s,
861                                        char **array,
862                                        w32 &total,
863                                        w32 &line_on,
864                                        char *error_prefix,
865                                        char *token_buf)
866{   
867  char *t1;
868  total=0;
869  while (*s)
870  {
871    t1=token_buf;
872    get_token(s,t1,line_on,error_prefix);
873    *t1=0;
874    if (token_buf[0]=='}' && token_buf[1]==0)
875      return ;
876
877    array[total]=alloc_str(token_buf);
878    total++;
879  }
880  i4_error("%s:%d: expecting }",error_prefix,line_on);
881}
882
883
884
885void i4_string_manager_class::get_token(char *&s, char *&buf, w32 &line_on, char *error_prefix)
886
887{
888  char *sl=s;
889  skip_white(sl,line_on);
890  if (*sl=='"')
891  {
892    sl++;
893    while (*sl && *sl!='"')
894      get_char(sl,buf,line_on,error_prefix);
895    if (*sl==0)
896      i4_error("%s:%d:expected %c",error_prefix,line_on,'"');
897    else
898      sl++;
899  }
900  else
901  {
902    if (*sl=='=' || *sl=='{' || *sl=='}' || *sl=='#')
903    {
904      *buf=*sl;
905      sl++;
906      buf++;
907    }
908    else
909    {
910      while (*sl &&
911             !space_char(*sl) &&
912             *sl!='=' && *sl!='}' && *sl!='{')
913        get_char(sl,buf,line_on,error_prefix);
914    }
915  }
916  s=sl;
917
918}
919
920
921
922i4_bool i4_string_manager_class::load_buffer(void *internal_buffer, char *error_prefix)
923{
924  char *s=(char *)internal_buffer;
925  char *token1,*token2,*t1,*t2;
926  char **array;
927  w32 line_on=1;
928
929  token1 = (char *)i4_malloc(4000,"token1 buf");
930  token2 = (char *)i4_malloc(4000,"token2 buf");
931  array  = (char **)i4_malloc(1000*sizeof(char *),"array buf");
932
933 
934  dump_file_buf=internal_buffer;
935  dump_buf_len=strlen((char *)internal_buffer);
936
937
938  while (*s)
939  {
940    t1=token1; 
941    get_token(s,t1,line_on,error_prefix); 
942    *t1=0;
943
944    if (token1[0]=='=' && token1[1]==0)
945      i4_error("%s:%d: expected token not =", error_prefix, line_on);
946    else if (token1[0]=='{')
947      i4_error("%s:%d: expected token not {", error_prefix, line_on);       
948    else if (token1[0]=='#')
949    {
950      t1=token1; 
951      get_token(s,t1,line_on,error_prefix); 
952      *t1=0;
953      if (strcmp(token1,"include"))
954        i4_error("%s:%d: expected include", error_prefix, line_on);
955
956      t1=token1; 
957      get_token(s,t1,line_on,error_prefix); 
958      *t1=0; 
959      load(token1);
960    }
961    else
962    {
963      t2=token2;   
964      get_token(s,t2,line_on,error_prefix); 
965      *t2=0;
966      if (token2[0]=='=' && token2[1]==0)   // it's ok to have an equal here
967      {
968        t2=token2;
969        get_token(s,t2,line_on,error_prefix);
970        *t2=0;
971      }
972
973      if (token2[0]=='{' && token2[1]==0)
974      {
975        w32 total;
976        read_array(s, array, total, line_on, error_prefix, token2);
977        add_array_node(token1,array, total);
978      }
979      else
980      {
981        //        printf("'%s' : '%s'\n",token1,token2);
982        add_node(token1,token2);
983      }
984    }
985
986    skip_white(s,line_on);
987  }
988 
989  i4_free(token1);
990  i4_free(token2);
991  i4_free(array);
992
993  return i4_T;
994}
995
996
997i4_bool i4_string_manager_class::load(const i4_const_str &filename)
998{
999  return load(filename.ptr);
1000}
1001
1002
1003i4_bool i4_string_manager_class::load(char *filename)
1004{
1005  i4_file_class *fp;
1006  i4_const_str tmp(filename);
1007
1008  fp=i4_open(tmp);
1009   
1010  if (!fp)
1011  {
1012    i4_warning("include file %s missing",filename);
1013    return i4_F;
1014  }
1015  else
1016  {
1017    w32 size=fp->size();
1018    char *mem=(char *)i4_malloc(size+1,"tmp");   
1019    if (fp->read(mem,size)!=size)
1020    {
1021      delete fp;
1022      return i4_F;
1023    }
1024    mem[size]=0;
1025
1026    load_buffer(mem,filename);
1027    i4_free(mem);
1028    delete fp;
1029  }
1030  return i4_T;
1031}
1032
1033
1034
1035
1036char *i4_os_string(const i4_const_str &name, char *tmp_buf, int buflen)
1037{
1038  i4_const_str::iterator p=name.begin();
1039  char *s=tmp_buf;
1040  while (p!=name.end() && buflen>1)
1041  {
1042    *s=(char)p.get().value();
1043    ++s;
1044    ++p;
1045    buflen--;
1046  }
1047  *s=0;
1048
1049  return tmp_buf;
1050}
1051
1052i4_str *i4_from_ascii(const char *buf)
1053{
1054  int l=strlen(buf);
1055  i4_str *ret=new i4_str(l);
1056  ret->len=l;
1057  memcpy(ret->ptr, buf, l);
1058  return ret;
1059}
1060
1061
1062const i4_const_str &i4gets(char *str, i4_bool barf_on_error)
1063{
1064  const i4_const_str *s=&i4_string_man.get(str);
1065  if (barf_on_error && s->null())
1066    i4_error("Resource missing %s",str);
1067  return *s;
1068}
1069
1070int i4getn(char *str, i4_bool barf_on_error)
1071{
1072  i4_const_str::iterator i=i4gets(str, barf_on_error).begin();
1073  return i.read_number();
1074}
Note: See TracBrowser for help on using the repository browser.