@@ -148,6 +148,124 @@ double_length(double d) {
148148 return ret ;
149149}
150150
151+
152+ int
153+ redis_cmd_format_static (char * * ret , char * keyword , char * format , ...) {
154+
155+ char * p , * s ;
156+ va_list ap ;
157+
158+ int total = 0 , sz , ret_sz ;
159+ int i , ci ;
160+ unsigned int u ;
161+ double dbl ;
162+ char * double_str ;
163+ int double_len ;
164+
165+ int stage ; /* 0: count & alloc. 1: copy. */
166+ int elements = strlen (format );
167+ int keyword_len = strlen (keyword );
168+ int header_sz = 1 + integer_length (1 + elements ) + 2 /* star + elements + CRLF */
169+ + 1 + integer_length (keyword_len ) + 2 /* dollar + command length + CRLF */
170+ + keyword_len + 2 ; /* command + CRLF */
171+
172+ for (stage = 0 ; stage < 2 ; ++ stage ) {
173+ va_start (ap , format );
174+ if (stage == 0 ) {
175+ total = 0 ;
176+ } else {
177+ total = header_sz ;
178+ }
179+ for (p = format ; * p ; ) {
180+ switch (* p ) {
181+ case 's' :
182+ s = va_arg (ap , char * );
183+ sz = va_arg (ap , int );
184+ if (stage == 1 ) {
185+ memcpy ((* ret ) + total , "$" , 1 ); /* dollar */
186+ total ++ ;
187+
188+ sprintf ((* ret ) + total , "%d" , sz ); /* size */
189+ total += integer_length (sz );
190+
191+ memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
192+ total += 2 ;
193+
194+ memcpy ((* ret ) + total , s , sz ); /* string */
195+ total += sz ;
196+
197+ memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
198+ total += 2 ;
199+ } else {
200+ total += 1 + integer_length (sz ) + 2 + sz + 2 ;
201+ }
202+ break ;
203+
204+ case 'F' :
205+ case 'f' :
206+ /* use spprintf here */
207+ dbl = va_arg (ap , double );
208+ sz = double_length (dbl );
209+ if (stage == 1 ) {
210+ memcpy ((* ret ) + total , "$" , 1 ); /* dollar */
211+ total ++ ;
212+
213+ sprintf ((* ret ) + total , "%d" , sz ); /* size */
214+ total += integer_length (sz );
215+
216+ memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
217+ total += 2 ;
218+
219+ sprintf ((* ret ) + total , "%F" , dbl ); /* float */
220+ total += sz ;
221+
222+ memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
223+ total += 2 ;
224+ } else {
225+ total += 1 + integer_length (sz ) + 2 + sz + 2 ;
226+ }
227+ break ;
228+
229+ case 'i' :
230+ case 'd' :
231+ i = va_arg (ap , int );
232+ /* compute display size of integer value */
233+ sz = integer_length (i );
234+ if (stage == 1 ) {
235+ memcpy ((* ret ) + total , "$" , 1 ); /* dollar */
236+ total ++ ;
237+
238+ sprintf ((* ret ) + total , "%d" , sz ); /* size */
239+ total += integer_length (sz );
240+
241+ memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
242+ total += 2 ;
243+
244+ sprintf ((* ret ) + total , "%d" , i ); /* int */
245+ total += sz ;
246+
247+ memcpy ((* ret ) + total , _NL , 2 ); /* CRLF */
248+ total += 2 ;
249+ } else {
250+ total += 1 + integer_length (sz ) + 2 + sz + 2 ;
251+ }
252+ break ;
253+ }
254+ p ++ ;
255+ }
256+ if (stage == 0 ) {
257+ ret_sz = total + header_sz ;
258+ (* ret ) = emalloc (ret_sz + 1 );
259+ sprintf (* ret , "*%d" _NL "$%d" _NL "%s" _NL , elements + 1 , keyword_len , keyword );
260+ } else {
261+ (* ret )[ret_sz ] = 0 ;
262+ // printf("cmd(%d)=[%s]\n", ret_sz, *ret);
263+ return ret_sz ;
264+ }
265+ }
266+
267+ }
268+
151269/**
152270 * This command behave somehow like printf, except that strings need 2 arguments:
153271 * Their data and their size (strlen).
0 commit comments