github.com/akaros/go-akaros@v0.0.0-20181004170632-85005d477eab/src/lib9/fmt/vsmprint.c (about)

     1  /*
     2   * The authors of this software are Rob Pike and Ken Thompson,
     3   * with contributions from Mike Burrows and Sean Dorward.
     4   *
     5   *     Copyright (c) 2002-2006 by Lucent Technologies.
     6   *     Portions Copyright (c) 2004 Google Inc.
     7   * 
     8   * Permission to use, copy, modify, and distribute this software for any
     9   * purpose without fee is hereby granted, provided that this entire notice
    10   * is included in all copies of any software which is or includes a copy
    11   * or modification of this software and in all copies of the supporting
    12   * documentation for such software.
    13   * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
    14   * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES 
    15   * NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING 
    16   * THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
    17   */
    18  
    19  #include <u.h>
    20  #include <libc.h>
    21  #include "fmtdef.h"
    22  
    23  static int
    24  fmtStrFlush(Fmt *f)
    25  {
    26  	char *s;
    27  	int n;
    28  
    29  	if(f->start == nil)
    30  		return 0;
    31  	n = (int)(uintptr)f->farg;
    32  	n *= 2;
    33  	s = (char*)f->start;
    34  	f->start = realloc(s, (size_t)n);
    35  	if(f->start == nil){
    36  		f->farg = nil;
    37  		f->to = nil;
    38  		f->stop = nil;
    39  		free(s);
    40  		return 0;
    41  	}
    42  	f->farg = (void*)(uintptr)n;
    43  	f->to = (char*)f->start + ((char*)f->to - s);
    44  	f->stop = (char*)f->start + n - 1;
    45  	return 1;
    46  }
    47  
    48  int
    49  fmtstrinit(Fmt *f)
    50  {
    51  	int n;
    52  
    53  	memset(f, 0, sizeof *f);
    54  	f->runes = 0;
    55  	n = 32;
    56  	f->start = malloc((size_t)n);
    57  	if(f->start == nil)
    58  		return -1;
    59  	f->to = f->start;
    60  	f->stop = (char*)f->start + n - 1;
    61  	f->flush = fmtStrFlush;
    62  	f->farg = (void*)(uintptr)n;
    63  	f->nfmt = 0;
    64  	fmtlocaleinit(f, nil, nil, nil);
    65  	return 0;
    66  }
    67  
    68  /*
    69   * print into an allocated string buffer
    70   */
    71  char*
    72  vsmprint(char *fmt, va_list args)
    73  {
    74  	Fmt f;
    75  	int n;
    76  
    77  	if(fmtstrinit(&f) < 0)
    78  		return nil;
    79  	VA_COPY(f.args,args);
    80  	n = dofmt(&f, fmt);
    81  	VA_END(f.args);
    82  	if(n < 0){
    83  		free(f.start);
    84  		return nil;
    85  	}
    86  	return fmtstrflush(&f);
    87  }