iPXE
efi_strings.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 #include <stddef.h>
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <ipxe/vsprintf.h>
32 #include <ipxe/efi/efi_strings.h>
33 
34 /** Context used by efi_vsnprintf() and friends */
36  /** printf context */
38  /** Buffer for formatted string (used by efi_printf_sputc()) */
39  wchar_t *buf;
40  /** Buffer length (used by efi_printf_sputc())
41  *
42  * Note that this is a number of wide characters, not a number
43  * of bytes.
44  */
45  size_t max_wlen;
46 };
47 
48 /**
49  * Write wide character to buffer
50  *
51  * @v ctx Context
52  * @v c Character
53  */
54 static void efi_printf_sputc ( struct printf_context *ctx, unsigned int c ) {
55  struct efi_sputc_context * sctx =
57 
58  if ( ctx->len < sctx->max_wlen )
59  sctx->buf[ctx->len] = c;
60 }
61 
62 /**
63  * Write a formatted string to a wide-character buffer
64  *
65  * @v wbuf Buffer into which to write the string
66  * @v wsize Size of buffer (in wide characters)
67  * @v fmt Format string
68  * @v args Arguments corresponding to the format string
69  * @ret wlen Length of formatted string (in wide characters)
70  *
71  * If the buffer is too small to contain the string, the returned
72  * length is the length that would have been written had enough space
73  * been available.
74  */
75 int efi_vsnprintf ( wchar_t *wbuf, size_t wsize, const char *fmt,
76  va_list args ) {
77  struct efi_sputc_context sctx;
78  size_t wlen;
79  size_t wend;
80 
81  /* Hand off to vcprintf */
83  sctx.buf = wbuf;
84  sctx.max_wlen = wsize;
85  wlen = vcprintf ( &sctx.ctx, fmt, args );
86 
87  /* Add trailing NUL */
88  if ( wsize ) {
89  wend = wsize - 1;
90  if ( wlen < wend )
91  wend = wlen;
92  wbuf[wend] = '\0';
93  }
94 
95  return wlen;
96 }
97 
98 /**
99  * Write a formatted string to a buffer
100  *
101  * @v wbuf Buffer into which to write the string
102  * @v wsize Size of buffer (in wide characters)
103  * @v fmt Format string
104  * @v ... Arguments corresponding to the format string
105  * @ret wlen Length of formatted string (in wide characters)
106  */
107 int efi_snprintf ( wchar_t *wbuf, size_t wsize, const char *fmt, ... ) {
108  va_list args;
109  int i;
110 
111  va_start ( args, fmt );
112  i = efi_vsnprintf ( wbuf, wsize, fmt, args );
113  va_end ( args );
114  return i;
115 }
116 
117 /**
118  * Version of efi_vsnprintf() that accepts a signed buffer size
119  *
120  * @v wbuf Buffer into which to write the string
121  * @v swsize Size of buffer (in wide characters)
122  * @v fmt Format string
123  * @v args Arguments corresponding to the format string
124  * @ret wlen Length of formatted string (in wide characters)
125  */
126 int efi_vssnprintf ( wchar_t *wbuf, ssize_t swsize, const char *fmt,
127  va_list args ) {
128 
129  /* Treat negative buffer size as zero buffer size */
130  if ( swsize < 0 )
131  swsize = 0;
132 
133  /* Hand off to vsnprintf */
134  return efi_vsnprintf ( wbuf, swsize, fmt, args );
135 }
136 
137 /**
138  * Version of efi_vsnprintf() that accepts a signed buffer size
139  *
140  * @v wbuf Buffer into which to write the string
141  * @v swsize Size of buffer (in wide characters)
142  * @v fmt Format string
143  * @v ... Arguments corresponding to the format string
144  * @ret wlen Length of formatted string (in wide characters)
145  */
146 int efi_ssnprintf ( wchar_t *wbuf, ssize_t swsize, const char *fmt, ... ) {
147  va_list args;
148  int len;
149 
150  /* Hand off to vssnprintf */
151  va_start ( args, fmt );
152  len = efi_vssnprintf ( wbuf, swsize, fmt, args );
153  va_end ( args );
154  return len;
155 }
156 
157 /**
158  * Write a formatted string to newly allocated memory
159  *
160  * @v wstrp Pointer to hold allocated string
161  * @v fmt Format string
162  * @v args Arguments corresponding to the format string
163  * @ret len Length of formatted string (in wide characters)
164  */
165 int efi_vasprintf ( wchar_t **wstrp, const char *fmt, va_list args ) {
166  size_t len;
167  va_list args_tmp;
168 
169  /* Calculate length needed for string */
170  va_copy ( args_tmp, args );
171  len = ( efi_vsnprintf ( NULL, 0, fmt, args_tmp ) + 1 );
172  va_end ( args_tmp );
173 
174  /* Allocate and fill string */
175  *wstrp = malloc ( len * sizeof ( **wstrp ) );
176  if ( ! *wstrp )
177  return -ENOMEM;
178  return efi_vsnprintf ( *wstrp, len, fmt, args );
179 }
180 
181 /**
182  * Write a formatted string to newly allocated memory
183  *
184  * @v wstrp Pointer to hold allocated string
185  * @v fmt Format string
186  * @v ... Arguments corresponding to the format string
187  * @ret len Length of formatted string (in wide characters)
188  */
189 int efi_asprintf ( wchar_t **wstrp, const char *fmt, ... ) {
190  va_list args;
191  int len;
192 
193  va_start ( args, fmt );
194  len = efi_vasprintf ( wstrp, fmt, args );
195  va_end ( args );
196  return len;
197 }
struct printf_context ctx
printf context
Definition: efi_strings.c:37
#define va_end(ap)
Definition: stdarg.h:10
void(* handler)(struct printf_context *ctx, unsigned int c)
Character handler.
Definition: vsprintf.h:58
Error codes.
int efi_vsnprintf(wchar_t *wbuf, size_t wsize, const char *fmt, va_list args)
Write a formatted string to a wide-character buffer.
Definition: efi_strings.c:75
EFI strings.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
printf() and friends
wchar_t * buf
Buffer for formatted string (used by efi_printf_sputc())
Definition: efi_strings.c:39
int efi_vasprintf(wchar_t **wstrp, const char *fmt, va_list args)
Write a formatted string to newly allocated memory.
Definition: efi_strings.c:165
#define va_copy(dest, src)
Definition: stdarg.h:11
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define ENOMEM
Not enough space.
Definition: errno.h:535
FILE_SECBOOT(PERMITTED)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
ring len
Length.
Definition: dwmac.h:231
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:107
static void efi_printf_sputc(struct printf_context *ctx, unsigned int c)
Write wide character to buffer.
Definition: efi_strings.c:54
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
A printf context.
Definition: vsprintf.h:48
size_t max_wlen
Buffer length (used by efi_printf_sputc())
Definition: efi_strings.c:45
__builtin_va_list va_list
Definition: stdarg.h:7
int efi_vssnprintf(wchar_t *wbuf, ssize_t swsize, const char *fmt, va_list args)
Version of efi_vsnprintf() that accepts a signed buffer size.
Definition: efi_strings.c:126
int ssize_t const char * fmt
Definition: vsprintf.h:73
Context used by efi_vsnprintf() and friends.
Definition: efi_strings.c:35
signed long ssize_t
Definition: stdint.h:7
#define va_start(ap, last)
Definition: stdarg.h:8
int efi_asprintf(wchar_t **wstrp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition: efi_strings.c:189
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
int efi_ssnprintf(wchar_t *wbuf, ssize_t swsize, const char *fmt,...)
Version of efi_vsnprintf() that accepts a signed buffer size.
Definition: efi_strings.c:146
size_t vcprintf(struct printf_context *ctx, const char *fmt, va_list args)
Write a formatted string to a printf context.
Definition: vsprintf.c:188