Skip to content

Commit a33f7de

Browse files
nordic-krchnashif
authored andcommitted
lib: os: cbprintf: Add CBPRINTF_PACKAGE_COPY_KEEP_RO_STR flag
Add flag to copy function which indicates that read-only string locations shall be kept in the output package. Updated cbprintf_package test to pass. Signed-off-by: Krzysztof Chruscinski <[email protected]>
1 parent 694ad59 commit a33f7de

File tree

3 files changed

+60
-21
lines changed

3 files changed

+60
-21
lines changed

include/sys/cbprintf.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,18 @@ BUILD_ASSERT(Z_IS_POW2(CBPRINTF_PACKAGE_ALIGNMENT));
131131
* is set, list of read-write strings is examined and if they are not determined
132132
* to be read-only, they are copied into the destination package.
133133
* If @ref CBPRINTF_PACKAGE_COPY_RO_STR is not set, remaining string locations
134-
* are considered as pointing to read-only location.
134+
* are considered as pointing to read-only location and they are copy to the
135+
* package if @ref CBPRINTF_PACKAGE_COPY_KEEP_RO_STR is set.
135136
*/
136137
#define CBPRINTF_PACKAGE_COPY_RW_STR BIT(1)
138+
139+
/** @brief Keep read-only location indexes in the package.
140+
*
141+
* If it is set read-only string pointers are kept in the package after copy. If
142+
* not set they are discarded.
143+
*/
144+
#define CBPRINTF_PACKAGE_COPY_KEEP_RO_STR BIT(2)
145+
137146
/**@} */
138147

139148
/** @brief Signature for a cbprintf callback function.

lib/os/cbprintf_packaged.c

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -733,10 +733,6 @@ int cbprintf_package_copy(void *in_packaged,
733733

734734
in_len != 0 ? in_len : get_package_len(in_packaged);
735735

736-
if (packaged && (len < in_len)) {
737-
return -ENOSPC;
738-
}
739-
740736
/* Get number of RO string indexes in the package and check if copying
741737
* includes appending those strings.
742738
*/
@@ -793,9 +789,15 @@ int cbprintf_package_copy(void *in_packaged,
793789
str_pos++;
794790
}
795791
} else {
796-
str_pos += ros_nbr;
792+
if (ros_nbr && flags & CBPRINTF_PACKAGE_COPY_KEEP_RO_STR) {
793+
str_pos += ros_nbr;
794+
}
797795
}
798796

797+
bool drop_ro_str_pos = !(flags &
798+
(CBPRINTF_PACKAGE_COPY_KEEP_RO_STR |
799+
CBPRINTF_PACKAGE_COPY_RO_STR));
800+
799801
/* Handle RW strings. */
800802
for (int i = 0; i < rws_nbr; i++) {
801803
const char *str = *(const char **)&buf32[*str_pos];
@@ -811,6 +813,14 @@ int cbprintf_package_copy(void *in_packaged,
811813
}
812814
out_len += len;
813815
}
816+
817+
if (is_ro && drop_ro_str_pos) {
818+
/* If read-only string location is dropped decreased
819+
* length.
820+
*/
821+
out_len--;
822+
}
823+
814824
str_pos++;
815825
}
816826

@@ -825,6 +835,9 @@ int cbprintf_package_copy(void *in_packaged,
825835
memcpy(dst, in_packaged, args_size);
826836
dst += args_size;
827837

838+
/* Pointer to the beginning of string locations in the destination package. */
839+
uint8_t *dst_str_loc = dst;
840+
828841
/* If read-only strings shall be appended to the output package copy
829842
* their indexes to the local array, otherwise indicate that indexes
830843
* shall remain in the output package.
@@ -837,10 +850,12 @@ int cbprintf_package_copy(void *in_packaged,
837850
str_pos += ros_nbr;
838851
} else {
839852
scpy_cnt = 0;
840-
if (ros_nbr) {
853+
if (ros_nbr && flags & CBPRINTF_PACKAGE_COPY_KEEP_RO_STR) {
841854
memcpy(dst, str_pos, ros_nbr);
842855
dst += ros_nbr;
843856
str_pos += ros_nbr;
857+
} else {
858+
dst_hdr[2] = 0;
844859
}
845860
}
846861

@@ -852,21 +867,30 @@ int cbprintf_package_copy(void *in_packaged,
852867
const char *str = *(const char **)&buf32[*str_pos];
853868
bool is_ro = ptr_in_rodata(str);
854869

855-
if ((is_ro && flags & CBPRINTF_PACKAGE_COPY_RO_STR) ||
856-
(!is_ro && flags & CBPRINTF_PACKAGE_COPY_RW_STR)) {
857-
cpy_str_pos[scpy_cnt++] = *str_pos;
870+
if (is_ro) {
871+
if (flags & CBPRINTF_PACKAGE_COPY_RO_STR) {
872+
cpy_str_pos[scpy_cnt++] = *str_pos;
873+
} else if (flags & CBPRINTF_PACKAGE_COPY_KEEP_RO_STR) {
874+
*dst++ = *str_pos;
875+
/* Increment amount of ro locations. */
876+
dst_hdr[2]++;
877+
} else {
878+
/* Drop information about ro_str location. */
879+
}
858880
} else {
859-
*dst++ = *str_pos;
881+
if (flags & CBPRINTF_PACKAGE_COPY_RW_STR) {
882+
cpy_str_pos[scpy_cnt++] = *str_pos;
883+
} else {
884+
*dst++ = *str_pos;
885+
}
860886
}
861887
str_pos++;
862888
}
863889

864-
uint8_t out_str_pos_nbr = ros_nbr + rws_nbr - scpy_cnt;
865-
866890
/* Increment amount of strings appended to the package. */
867891
dst_hdr[1] += scpy_cnt;
868892
/* Update number of rw string locations in the package. */
869-
dst_hdr[3] = out_str_pos_nbr - dst_hdr[2];
893+
dst_hdr[3] = (uint8_t)(uintptr_t)(dst - dst_str_loc) - dst_hdr[2];
870894

871895
/* Copy appended strings from source package to destination. */
872896
size_t strs_len = in_len - (args_size + ros_nbr + rws_nbr);
@@ -880,7 +904,7 @@ int cbprintf_package_copy(void *in_packaged,
880904
}
881905

882906
/* Calculate remaining space in the buffer. */
883-
size_t rem = len - (args_size + strs_len + out_str_pos_nbr);
907+
size_t rem = len - ((size_t)(uintptr_t)(dst - dst_hdr));
884908

885909
if (rem <= scpy_cnt) {
886910
return -ENOSPC;

tests/lib/cbprintf_package/src/main.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -525,17 +525,20 @@ static void test_cbprintf_ro_rw_loc(void)
525525
check_package(package, len, exp_str);
526526
check_package(cpackage, clen, exp_str);
527527

528+
uint32_t cpy_flags = CBPRINTF_PACKAGE_COPY_RW_STR |
529+
CBPRINTF_PACKAGE_COPY_KEEP_RO_STR;
530+
528531
/* Calculate size needed for package with appended read-write strings. */
529532
clen = cbprintf_package_copy(package, sizeof(package), NULL, 0,
530-
CBPRINTF_PACKAGE_COPY_RW_STR, NULL, 0);
533+
cpy_flags, NULL, 0);
531534

532535
/* Length will be increased by 2 string lengths + null terminators. */
533536
zassert_equal(clen, len + (int)strlen(test_str1) + (int)strlen(test_str2) + 2, NULL);
534537

535538
uint8_t __aligned(CBPRINTF_PACKAGE_ALIGNMENT) cpackage2[clen];
536539

537540
clen2 = cbprintf_package_copy(package, sizeof(package), cpackage2, sizeof(cpackage2),
538-
CBPRINTF_PACKAGE_COPY_RW_STR, NULL, 0);
541+
cpy_flags, NULL, 0);
539542

540543
zassert_equal(clen, clen2, NULL);
541544

@@ -717,26 +720,29 @@ static void test_cbprintf_rw_loc_const_char_ptr(void)
717720
zassert_equal(hdr[2], 0, NULL);
718721
zassert_equal(hdr[3], 2, NULL);
719722

723+
uint32_t cpy_flags = CBPRINTF_PACKAGE_COPY_RW_STR |
724+
CBPRINTF_PACKAGE_COPY_KEEP_RO_STR;
725+
720726
/* Calculate size needed for package with appended read-only strings. */
721727
clen = cbprintf_package_copy(spackage, sizeof(spackage), NULL, 0,
722-
CBPRINTF_PACKAGE_COPY_RW_STR, NULL, 0);
728+
cpy_flags, NULL, 0);
723729

724730
/* Length will be increased by 2 string lengths + null terminators. */
725731
zassert_equal(clen, slen + (int)strlen(test_str1) + 1, NULL);
726732

727733
uint8_t __aligned(CBPRINTF_PACKAGE_ALIGNMENT) cpackage[clen];
728734

729735
clen2 = cbprintf_package_copy(spackage, sizeof(spackage), cpackage, sizeof(cpackage),
730-
CBPRINTF_PACKAGE_COPY_RW_STR, NULL, 0);
736+
cpy_flags, NULL, 0);
731737

732738
zassert_equal(clen, clen2, NULL);
733739

734740
hdr = cpackage;
735741

736742
/* Check that one string has been appended. */
737743
zassert_equal(hdr[1], 1, NULL);
738-
zassert_equal(hdr[2], 0, NULL);
739-
zassert_equal(hdr[3], 1, NULL);
744+
zassert_equal(hdr[2], 1, NULL);
745+
zassert_equal(hdr[3], 0, NULL);
740746

741747
check_package(spackage, slen, exp_str);
742748
test_str1[0] = '\0';

0 commit comments

Comments
 (0)