File: asprintf.cpp

package info (click to toggle)
watchman 4.9.0-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,992 kB
  • sloc: cpp: 27,459; python: 6,538; java: 3,404; php: 3,257; ansic: 2,803; javascript: 1,116; makefile: 671; ruby: 364; sh: 124; xml: 102; lisp: 4
file content (52 lines) | stat: -rw-r--r-- 1,006 bytes parent folder | download | duplicates (3)
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
/* Copyright 2014-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */

#include "watchman.h"

// Poor-mans asprintf

int vasprintf(char **out, WATCHMAN_FMT_STRING(const char *fmt), va_list ap) {
  char stack[512];
  char *buf = stack;
  char *newbuf;
  int alloc = sizeof(stack);
  int len;

  while (1) {
    // For VC, returns -1 when it truncates
    len = _vsnprintf(buf, alloc, fmt, ap);

    if (len >= 0) {
      // It fits!
      if (buf == stack) {
        *out = strdup(buf);
        return len;
      }
      *out = buf;
      return len;
    }

    // Need a bigger boat
    alloc *= 2;
    newbuf = (char*)realloc(buf == stack ? NULL : buf, alloc);
    if (!newbuf) {
      if (buf != stack) {
        free(buf);
      }
      *out = NULL;
      return -1;
    }
    buf = newbuf;
  }
}

int asprintf(char **out, WATCHMAN_FMT_STRING(const char *fmt), ...) {
  va_list ap;
  int len;

  va_start(ap, fmt);
  len = vasprintf(out, fmt, ap);
  va_end(ap);

  return len;
}