Coverage Report

Created: 2026-05-30 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/flex/src/buf.c
Line
Count
Source
1
/* flex - tool to generate fast lexical analyzers */
2
3
/* SPDX-License-Identifier: BSD-3-Clause-flex */
4
5
/*  Copyright (c) 1990 The Regents of the University of California. */
6
/*  All rights reserved. */
7
8
/*  This code is derived from software contributed to Berkeley by */
9
/*  Vern Paxson. */
10
11
/*  The United States Government has rights in this work pursuant */
12
/*  to contract no. DE-AC03-76SF00098 between the United States */
13
/*  Department of Energy and the University of California. */
14
15
/*  This file is part of flex. */
16
17
/*  Redistribution and use in source and binary forms, with or without */
18
/*  modification, are permitted provided that the following conditions */
19
/*  are met: */
20
21
/*  1. Redistributions of source code must retain the above copyright */
22
/*     notice, this list of conditions and the following disclaimer. */
23
/*  2. Redistributions in binary form must reproduce the above copyright */
24
/*     notice, this list of conditions and the following disclaimer in the */
25
/*     documentation and/or other materials provided with the distribution. */
26
27
/*  Neither the name of the University nor the names of its contributors */
28
/*  may be used to endorse or promote products derived from this software */
29
/*  without specific prior written permission. */
30
31
/*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
32
/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
33
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
34
/*  PURPOSE. */
35

36
#include "flexdef.h"
37
38
/* Take note: The buffer object is sometimes used as a String buffer (one
39
 * continuous string), and sometimes used as a list of strings, usually line by
40
 * line.
41
 * 
42
 * The type is specified in buf_init by the elt_size. If the elt_size is
43
 * sizeof(char), then the buffer should be treated as string buffer. If the
44
 * elt_size is sizeof(char*), then the buffer should be treated as a list of
45
 * strings.
46
 *
47
 * Certain functions are only appropriate for one type or the other. 
48
 */
49
50
/* global buffers. */
51
struct Buf userdef_buf;   /**< for user #definitions triggered by cmd-line. */
52
struct Buf top_buf;             /**< contains %top code. String buffer. */
53
54
/* Append a "%s" formatted string to a string buffer */
55
struct Buf *buf_prints (struct Buf *buf, const char *fmt, const char *s)
56
0
{
57
0
  char   *t;
58
0
  size_t tsz;
59
60
0
  tsz = strlen(fmt) + strlen(s) + 1;
61
0
  t = malloc(tsz);
62
0
  if (!t)
63
0
      flexfatal (_("Allocation of buffer to print string failed"));
64
0
  snprintf (t, tsz, fmt, s);
65
0
  buf = buf_strappend (buf, t);
66
0
  free(t);
67
0
  return buf;
68
0
}
69
70
/* Appends n characters in str to buf. */
71
struct Buf *buf_strnappend (struct Buf *buf, const char *str, int n)
72
0
{
73
0
  buf_append (buf, str, n + 1);
74
75
  /* "undo" the '\0' character that buf_append() already copied. */
76
0
  buf->nelts--;
77
78
0
  return buf;
79
0
}
80
81
/* Appends characters in str to buf. */
82
struct Buf *buf_strappend (struct Buf *buf, const char *str)
83
0
{
84
0
  return buf_strnappend (buf, str, (int) strlen (str));
85
0
}
86
87
/* create buf with 0 elements, each of size elem_size. */
88
void buf_init (struct Buf *buf, size_t elem_size)
89
0
{
90
0
  buf->elts = NULL;
91
0
  buf->nelts = 0;
92
0
  buf->elt_size = elem_size;
93
0
  buf->nmax = 0;
94
0
}
95
96
/* frees memory */
97
void buf_destroy (struct Buf *buf)
98
0
{
99
0
  if (buf) {
100
0
    free(buf->elts);
101
0
    buf->elts = NULL;
102
0
  }
103
0
}
104
105
106
/* appends ptr[] to buf, grow if necessary.
107
 * n_elem is number of elements in ptr[], NOT bytes.
108
 * returns buf.
109
 * We grow by mod(512) boundaries.
110
 */
111
112
struct Buf *buf_append (struct Buf *buf, const void *ptr, int n_elem)
113
0
{
114
0
  int     n_alloc = 0;
115
116
0
  if (!ptr || n_elem == 0)
117
0
    return buf;
118
119
  /* May need to alloc more. */
120
0
  if (n_elem + buf->nelts > buf->nmax) {
121
122
    /* exact count needed... */
123
0
    n_alloc = n_elem + buf->nelts;
124
125
    /* ...plus some extra */
126
0
    if ((((size_t) n_alloc * buf->elt_size) % 512) != 0
127
0
        && buf->elt_size < 512)
128
0
      n_alloc += (int)
129
0
        ((512 -
130
0
         (((size_t) n_alloc * buf->elt_size) % 512)) /
131
0
        buf->elt_size);
132
133
0
    if (!buf->elts)
134
0
      buf->elts =
135
0
        allocate_array ((int) n_alloc, buf->elt_size);
136
0
    else
137
0
      buf->elts =
138
0
        reallocate_array (buf->elts, (int) n_alloc,
139
0
              buf->elt_size);
140
141
0
    buf->nmax = n_alloc;
142
0
  }
143
144
0
  memcpy ((char *) buf->elts + (size_t) buf->nelts * buf->elt_size, ptr,
145
0
    (size_t) n_elem * buf->elt_size);
146
0
  buf->nelts += n_elem;
147
148
0
  return buf;
149
0
}
150
151
/* vim:set tabstop=8 softtabstop=4 shiftwidth=4: */