summaryrefslogtreecommitdiff
path: root/debian/patches/11-sync-libs-with-plan9port.patch
blob: 8e87eb0abf9c10b52fefcdffbdbef6cfbcc52931 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
Description: 9libs: Sync with plan9port.
 This patch is imported from the upstream's VCS.
Author: Kris Maglione <kris@suckless.org>
Origin: upstream, http://hg.suckless.org/wmii/raw-rev/d1296b42f38a

--- a/include/fmt.h
+++ b/include/fmt.h
@@ -27,10 +27,22 @@
 	void	*farg;			/* to make flush a closure */
 	int	nfmt;			/* num chars formatted so far */
 	va_list	args;			/* args passed to dofmt */
-	int	r;			/* % format Rune */
+	Rune	r;			/* % format Rune */
 	int	width;
 	int	prec;
 	unsigned long	flags;
+	char	*decimal;	/* decimal point; cannot be "" */
+
+	/* For %'d */
+	char *thousands;	/* separator for thousands */
+	
+	/* 
+	 * Each char is an integer indicating #digits before next separator. Values:
+	 *	\xFF: no more grouping (or \x7F; defined to be CHAR_MAX in POSIX)
+	 *	\x00: repeat previous indefinitely
+	 *	\x**: count that many
+	 */
+	char	*grouping;		/* descriptor of separator placement */
 };
 
 enum{
@@ -40,7 +52,8 @@
 	FmtSharp	= FmtPrec << 1,
 	FmtSpace	= FmtSharp << 1,
 	FmtSign		= FmtSpace << 1,
-	FmtZero		= FmtSign << 1,
+	FmtApost		= FmtSign << 1,
+	FmtZero		= FmtApost << 1,
 	FmtUnsigned	= FmtZero << 1,
 	FmtShort	= FmtUnsigned << 1,
 	FmtLong		= FmtShort << 1,
@@ -121,6 +134,7 @@
 int		fmtfdflush(Fmt*);
 int		fmtfdinit(Fmt*, int fd, char *buf, int size);
 int		fmtinstall(int, int (*f)(Fmt*));
+void		fmtlocaleinit(Fmt*, char *decimal, char *thousands, char *grouping);
 int		fmtprint(Fmt*, const char*, ...);
 int		fmtrune(Fmt*, int);
 int		fmtrunestrcpy(Fmt*, Rune*);
--- a/include/utf.h
+++ b/include/utf.h
@@ -1,14 +1,15 @@
 #ifndef _UTF_H_
 #define _UTF_H_ 1
 
-typedef unsigned short Rune;	/* 16 bits */
+typedef unsigned int Rune;	/* 32 bits */
 
 enum
 {
-	UTFmax		= 3,		/* maximum bytes per rune */
+	UTFmax		= 4,		/* maximum bytes per rune */
 	Runesync	= 0x80,		/* cannot represent part of a UTF sequence (<) */
 	Runeself	= 0x80,		/* rune and UTF sequences are the same (<) */
-	Runeerror	= 0xFFFD,		/* decoding error in UTF */
+	Runeerror	= 0xFFFD,	/* decoding error in UTF */
+	Runemax		= 0x10FFFF	/* maximum rune value */
 };
 
 /* Edit .+1,/^$/ | cfn $PLAN9/src/lib9/utf/?*.c | grep -v static |grep -v __ */
@@ -19,7 +20,7 @@
 int		isspacerune(Rune);
 int		istitlerune(Rune);
 int		isupperrune(Rune);
-int		runelen(Rune);
+int		runelen(long);
 int		runenlen(const Rune*, int);
 Rune*		runestrcat(Rune*, const Rune*);
 Rune*		runestrchr(const Rune*, Rune);
--- /dev/null
+++ b/lib/libfmt/fmtlocale.c
@@ -0,0 +1,55 @@
+/* Copyright (c) 2004 Google Inc.; see LICENSE */
+
+#include <stdarg.h>
+#include <string.h>
+#include "plan9.h"
+#include "fmt.h"
+#include "fmtdef.h"
+
+/*
+ * Fill in the internationalization stuff in the State structure.
+ * For nil arguments, provide the sensible defaults:
+ *	decimal is a period
+ *	thousands separator is a comma
+ *	thousands are marked every three digits
+ */
+void
+fmtlocaleinit(Fmt *f, char *decimal, char *thousands, char *grouping)
+{
+	if(decimal == nil || decimal[0] == '\0')
+		decimal = ".";
+	if(thousands == nil)
+		thousands = ",";
+	if(grouping == nil)
+		grouping = "\3";
+	f->decimal = decimal;
+	f->thousands = thousands;
+	f->grouping = grouping;
+}
+
+/*
+ * We are about to emit a digit in e.g. %'d.  If that digit would
+ * overflow a thousands (e.g.) grouping, tell the caller to emit
+ * the thousands separator.  Always advance the digit counter
+ * and pointer into the grouping descriptor.
+ */
+int
+__needsep(int *ndig, char **grouping)
+{
+	int group;
+	
+	(*ndig)++;
+	group = *(unsigned char*)*grouping;
+	/* CHAR_MAX means no further grouping. \0 means we got the empty string */
+	if(group == 0xFF || group == 0x7f || group == 0x00)
+		return 0;
+	if(*ndig > group){
+		/* if we're at end of string, continue with this grouping; else advance */
+		if((*grouping)[1] != '\0')
+			(*grouping)++;
+		*ndig = 1;
+		return 1;
+	}
+	return 0;
+}
+