A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

add memccpy.c

Not sure if this is worth the added bin size yet but I will
see where I can use it to try and make it worth it

Change-Id: Icc299d3986172ff224a14be48da3bf065d728a66

authored by

William Wilgus and committed by
William Wilgus
b25a9d8f 034b6d5b

+139 -5
+3 -1
apps/debug_menu.c
··· 1627 if (len >= name_sz) len = name_sz-1; 1628 slen += len; 1629 } 1630 - snprintf(str+slen, size-slen, "%s", buf); 1631 } 1632 1633 return 1; /* ok */
··· 1627 if (len >= name_sz) len = name_sz-1; 1628 slen += len; 1629 } 1630 + 1631 + if (!memccpy (str+slen, buf, '\0', size-slen)) 1632 + (str+slen)[size-slen - 1] = '\0'; 1633 } 1634 1635 return 1; /* ok */
+7 -2
apps/playlist_viewer.c
··· 516 { 517 char selected_track[MAX_PATH]; 518 close_playlist_viewer(); 519 - snprintf(selected_track, sizeof(selected_track), "%s", current_track->name); 520 521 return (filetype_list_viewers(selected_track) == 522 PLUGIN_USB_CONNECTED ? PV_ONPLAY_USB_CLOSED : PV_ONPLAY_CLOSED); ··· 528 { 529 char selected_track[MAX_PATH]; 530 close_playlist_viewer(); 531 - snprintf(selected_track, sizeof(selected_track), "%s", current_track->name); 532 533 return (filetype_load_plugin((void *)"pictureflow", selected_track) == 534 PLUGIN_USB_CONNECTED ? PV_ONPLAY_USB_CLOSED : PV_ONPLAY_CLOSED);
··· 516 { 517 char selected_track[MAX_PATH]; 518 close_playlist_viewer(); 519 + 520 + if (!memccpy (selected_track, current_track->name, '\0', sizeof(selected_track))) 521 + selected_track[sizeof(selected_track) - 1] = '\0'; 522 + 523 524 return (filetype_list_viewers(selected_track) == 525 PLUGIN_USB_CONNECTED ? PV_ONPLAY_USB_CLOSED : PV_ONPLAY_CLOSED); ··· 531 { 532 char selected_track[MAX_PATH]; 533 close_playlist_viewer(); 534 + 535 + if (!memccpy (selected_track, current_track->name, '\0', sizeof(selected_track))) 536 + selected_track[sizeof(selected_track) - 1] = '\0'; 537 538 return (filetype_load_plugin((void *)"pictureflow", selected_track) == 539 PLUGIN_USB_CONNECTED ? PV_ONPLAY_USB_CLOSED : PV_ONPLAY_CLOSED);
+8 -2
apps/screens.c
··· 561 case LANG_ID3_COMMENT: 562 if (!id3->comment) 563 return NULL; 564 - snprintf(buffer, buffer_len, "%s", id3->comment); 565 val=buffer; 566 if(say_it && val) 567 talk_spell(val, true); ··· 608 case LANG_FORMAT: 609 if (id3->codectype >= AFMT_NUM_CODECS) 610 return NULL; 611 - snprintf(buffer, buffer_len, "%s", audio_formats[id3->codectype].label); 612 val=buffer; 613 if(say_it) 614 talk_spell(val, true);
··· 561 case LANG_ID3_COMMENT: 562 if (!id3->comment) 563 return NULL; 564 + 565 + if (!memccpy (buffer, id3->comment, '\0', buffer_len)) 566 + buffer[buffer_len - 1] = '\0'; 567 + 568 val=buffer; 569 if(say_it && val) 570 talk_spell(val, true); ··· 611 case LANG_FORMAT: 612 if (id3->codectype >= AFMT_NUM_CODECS) 613 return NULL; 614 + 615 + if (!memccpy (buffer, audio_formats[id3->codectype].label, '\0', buffer_len)) 616 + buffer[buffer_len - 1] = '\0'; 617 + 618 val=buffer; 619 if(say_it) 620 talk_spell(val, true);
+1
firmware/SOURCES
··· 262 libc/sprintf.c 263 #endif 264 265 libc/memchr.c 266 libc/memcmp.c 267
··· 262 libc/sprintf.c 263 #endif 264 265 + libc/memccpy.c 266 libc/memchr.c 267 libc/memcmp.c 268
+1
firmware/libc/include/string.h
··· 20 _PTR _EXFUN(memchr,(const _PTR, int, size_t)); 21 int _EXFUN(memcmp,(const _PTR, const _PTR, size_t)); 22 _PTR _EXFUN(memcpy,(_PTR, const _PTR, size_t)); 23 _PTR _EXFUN(mempcpy,(_PTR, const _PTR, size_t)); 24 _PTR _EXFUN(memmove,(_PTR, const _PTR, size_t)); 25 _PTR _EXFUN(memset,(_PTR, int, size_t));
··· 20 _PTR _EXFUN(memchr,(const _PTR, int, size_t)); 21 int _EXFUN(memcmp,(const _PTR, const _PTR, size_t)); 22 _PTR _EXFUN(memcpy,(_PTR, const _PTR, size_t)); 23 + _PTR _EXFUN(memccpy,(_PTR, const _PTR, int, size_t)); 24 _PTR _EXFUN(mempcpy,(_PTR, const _PTR, size_t)); 25 _PTR _EXFUN(memmove,(_PTR, const _PTR, size_t)); 26 _PTR _EXFUN(memset,(_PTR, int, size_t));
+119
firmware/libc/memccpy.c
···
··· 1 + /* 2 + FUNCTION 3 + <<memccpy>>---copy memory regions with end-token check 4 + ANSI_SYNOPSIS 5 + #include <string.h> 6 + void* memccpy(void *restrict <[out]>, const void *restrict <[in]>, 7 + int <[endchar]>, size_t <[n]>); 8 + TRAD_SYNOPSIS 9 + void *memccpy(<[out]>, <[in]>, <[endchar]>, <[n]> 10 + void *<[out]>; 11 + void *<[in]>; 12 + int <[endchar]>; 13 + size_t <[n]>; 14 + DESCRIPTION 15 + This function copies up to <[n]> bytes from the memory region 16 + pointed to by <[in]> to the memory region pointed to by 17 + <[out]>. If a byte matching the <[endchar]> is encountered, 18 + the byte is copied and copying stops. 19 + If the regions overlap, the behavior is undefined. 20 + RETURNS 21 + <<memccpy>> returns a pointer to the first byte following the 22 + <[endchar]> in the <[out]> region. If no byte matching 23 + <[endchar]> was copied, then <<NULL>> is returned. 24 + PORTABILITY 25 + <<memccpy>> is a GNU extension. 26 + <<memccpy>> requires no supporting OS subroutines. 27 + */ 28 + #include <stddef.h> 29 + #include <string.h> 30 + #include <limits.h> 31 + #include "_ansi.h" /* for _DEFUN */ 32 + 33 + /* Nonzero if either X or Y is not aligned on a "long" boundary. */ 34 + #define ROCKBOX_UNALIGNED(X, Y) \ 35 + (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) 36 + /* How many bytes are copied each iteration of the word copy loop. */ 37 + #define LITTLEBLOCKSIZE (sizeof (long)) 38 + /* Threshhold for punting to the byte copier. */ 39 + #define TOO_SMALL(LEN) ((LEN) < LITTLEBLOCKSIZE) 40 + /* Macros for detecting endchar */ 41 + #if LONG_MAX == 2147483647L 42 + #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) 43 + #else 44 + #if LONG_MAX == 9223372036854775807L 45 + /* Nonzero if X (a long int) contains a NULL byte. */ 46 + #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) 47 + #else 48 + #error long int is not a 32bit or 64bit type. 49 + #endif 50 + #endif 51 + _PTR 52 + _DEFUN (memccpy, (dst0, src0, endchar, len0), 53 + _PTR __restrict dst0 _AND 54 + _CONST _PTR __restrict src0 _AND 55 + int endchar0 _AND 56 + size_t len0) 57 + { 58 + #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) 59 + _PTR ptr = NULL; 60 + char *dst = (char *) dst0; 61 + char *src = (char *) src0; 62 + char endchar = endchar0 & 0xff; 63 + while (len0--) 64 + { 65 + if ((*dst++ = *src++) == endchar) 66 + { 67 + ptr = dst; 68 + break; 69 + } 70 + } 71 + return ptr; 72 + #else 73 + _PTR ptr = NULL; 74 + char *dst = dst0; 75 + _CONST char *src = src0; 76 + long *aligned_dst; 77 + _CONST long *aligned_src; 78 + char endchar = endchar0 & 0xff; 79 + /* If the size is small, or either SRC or DST is unaligned, 80 + then punt into the byte copy loop. This should be rare. */ 81 + if (!TOO_SMALL(len0) && !ROCKBOX_UNALIGNED (src, dst)) 82 + { 83 + unsigned int i; 84 + unsigned long mask = 0; 85 + aligned_dst = (long*)dst; 86 + aligned_src = (long*)src; 87 + /* The fast code reads the ASCII one word at a time and only 88 + performs the bytewise search on word-sized segments if they 89 + contain the search character, which is detected by XORing 90 + the word-sized segment with a word-sized block of the search 91 + character and then detecting for the presence of NULL in the 92 + result. */ 93 + for (i = 0; i < LITTLEBLOCKSIZE; i++) 94 + mask = (mask << 8) + endchar; 95 + /* Copy one long word at a time if possible. */ 96 + while (len0 >= LITTLEBLOCKSIZE) 97 + { 98 + unsigned long buffer = (unsigned long)(*aligned_src); 99 + buffer ^= mask; 100 + if (DETECTNULL (buffer)) 101 + break; /* endchar is found, go byte by byte from here */ 102 + *aligned_dst++ = *aligned_src++; 103 + len0 -= LITTLEBLOCKSIZE; 104 + } 105 + /* Pick up any residual with a byte copier. */ 106 + dst = (char*)aligned_dst; 107 + src = (char*)aligned_src; 108 + } 109 + while (len0--) 110 + { 111 + if ((*dst++ = *src++) == endchar) 112 + { 113 + ptr = dst; 114 + break; 115 + } 116 + } 117 + return ptr; 118 + #endif /* not PREFER_SIZE_OVER_SPEED */ 119 + }