github.com/akaros/go-akaros@v0.0.0-20181004170632-85005d477eab/src/lib9/fmt/fmtlocale.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  /*
    24   * Fill in the internationalization stuff in the State structure.
    25   * For nil arguments, provide the sensible defaults:
    26   *	decimal is a period
    27   *	thousands separator is a comma
    28   *	thousands are marked every three digits
    29   */
    30  void
    31  fmtlocaleinit(Fmt *f, char *decimal, char *thousands, char *grouping)
    32  {
    33  	if(decimal == nil || decimal[0] == '\0')
    34  		decimal = ".";
    35  	if(thousands == nil)
    36  		thousands = ",";
    37  	if(grouping == nil)
    38  		grouping = "\3";
    39  	f->decimal = decimal;
    40  	f->thousands = thousands;
    41  	f->grouping = grouping;
    42  }
    43  
    44  /*
    45   * We are about to emit a digit in e.g. %'d.  If that digit would
    46   * overflow a thousands (e.g.) grouping, tell the caller to emit
    47   * the thousands separator.  Always advance the digit counter
    48   * and pointer into the grouping descriptor.
    49   */
    50  int
    51  __needsep(int *ndig, char **grouping)
    52  {
    53  	int group;
    54  
    55  	(*ndig)++;
    56  	group = *(unsigned char*)*grouping;
    57  	/* CHAR_MAX means no further grouping. \0 means we got the empty string */
    58  	if(group == 0xFF || group == 0x7f || group == 0x00)
    59  		return 0;
    60  	if(*ndig > group){
    61  		/* if we're at end of string, continue with this grouping; else advance */
    62  		if((*grouping)[1] != '\0')
    63  			(*grouping)++;
    64  		*ndig = 1;
    65  		return 1;
    66  	}
    67  	return 0;
    68  }
    69