mpg123 1.33.0-dev+20250525022201

This commit is contained in:
Ozkan Sezer
2025-05-25 20:40:02 +03:00
parent 22dadfaa3c
commit bf2eba7bc0
28 changed files with 433 additions and 112 deletions

View File

@@ -110,8 +110,17 @@
typedef unsigned char byte;
// Annoying hackery to select a safe strtok variant. MS decided to call their strtok_r strtok_s, while
// C11 declares another strtok_s with different prototype. Thanks to you all.
#ifdef HAVE_STRTOK_R
#define INT123_compat_strtok(a, b, c) strtok_r((a), (b), (c))
#endif
#if (defined(_UCRT) || defined(_MSC_VER) || (defined(__MINGW32__) || defined(__MINGW64__)) || (defined(__WATCOMC__) && defined(__NT__))) && !defined(__CYGWIN__)
#define MPG123_COMPAT_MSVCRT_IO
#ifndef INT123_compat_strtok
#define INT123_compat_strtok(a, b, c) strtok_s((a), (b), (c))
#endif
#endif
#if defined(MPG123_COMPAT_MSVCRT_IO)
@@ -150,6 +159,11 @@ typedef unsigned char byte;
#include <io.h>
#endif
#ifndef INT123_compat_strtok
#warning "no safe strtok found"
#define INT123_compat_strtok(a, b, c) strtok((a), (b))
#endif
/* A safe realloc also for very old systems where realloc(NULL, size) returns NULL. */
void *INT123_safe_realloc(void *ptr, size_t size);
// Also freeing ptr if result is NULL. You can do

View File

@@ -49,9 +49,9 @@
#include "../common/debug.h"
#include "wpathconv.h"
#ifdef USE_MODULES
#include "wpathconv.h"
/*
This is what I expected the platform-specific dance for dynamic module
support to be. Little did I know about the peculiarities of (long)

View File

@@ -244,6 +244,12 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtok_r' function. */
#undef HAVE_STRTOK_R
/* Define to 1 if you have the `strtok_s' function. */
#undef HAVE_STRTOK_S
/* Define to 1 if you have the <sun/audioio.h> header file. */
#undef HAVE_SUN_AUDIOIO_H

View File

@@ -780,8 +780,9 @@ int control_generic (mpg123_handle *fr)
/* commands with arguments */
cmd = NULL;
arg = NULL;
cmd = strtok(comstr," \t"); /* get the main command */
arg = strtok(NULL,""); /* get the args */
char *toksave = NULL;
cmd = INT123_compat_strtok(comstr, " \t", &toksave); /* get the main command */
arg = INT123_compat_strtok(NULL, "", &toksave); /* get the args */
if (cmd && strlen(cmd) && arg && strlen(arg))
{

View File

@@ -13,11 +13,15 @@
/** \file mpg123.h The header file for the libmpg123 MPEG Audio decoder */
/** \defgroup mpg123_h mpg123 header general settings and notes
* @{
*/
/** A macro to check at compile time which set of API functions to expect.
* This must be incremented at least each time a new symbol is added
* to the header.
*/
#define MPG123_API_VERSION 48
#define MPG123_API_VERSION 49
/** library patch level at client build time */
#define MPG123_PATCHLEVEL 3
@@ -43,8 +47,10 @@
#endif
#endif
/** Earlier versions of libmpg123 put enums into public API calls,
* thich is not exactly safe. There are ABI rules, but you can use
/** \page enumapi About enum API
*
* Earlier versions of libmpg123 put enums into public API calls,
* which is not exactly safe. There are ABI rules, but you can use
* compiler switches to change the sizes of enums. It is safer not
* to have them in API calls. Thus, the default is to remap calls and
* structs to variants that use plain ints. Define MPG123_ENUM_API to
@@ -53,6 +59,21 @@
* You might want to define this to increase the chance of your binary
* working with an older version of the library. But if that is your goal,
* you should better build with an older version to begin with.
*
* You can avoid renamed symbols by using the non-enum names directly:
*
* - mpg123_param2()
* - mpg123_getparam2()
* - mpg123_feature2()
* - mpg123_eq2()
* - mpg123_geteq2()
* - mpg123_frameinfo2()
* - mpg123_info2()
* - mpg123_getstate2()
* - mpg123_enc_from_id3_2()
* - mpg123_store_utf8_2()
* - mpg123_par2()
* - mpg123_getpar2()
*/
#ifndef MPG123_ENUM_API
@@ -76,7 +97,7 @@
#ifndef MPG123_PORTABLE_API
#include <sys/types.h>
/* A little hack to help MSVC not having ssize_t. */
/** A little hack to help MSVC not having ssize_t. */
#ifdef _MSC_VER
typedef ptrdiff_t mpg123_ssize_t;
#else
@@ -85,26 +106,61 @@ typedef ssize_t mpg123_ssize_t;
#endif
/* Handling of large file offsets.
When client code defines _FILE_OFFSET_BITS, it wants non-default large file support,
and thus functions with added suffix (mpg123_open_64). The default library build provides
wrapper and alias functions to accomodate client code variations (dual-mode library like glibc).
Client code can definie MPG123_NO_LARGENAME and MPG123_LARGESUFFIX, respectively, for disabling
or enforcing the suffixes. If explicit usage of 64 bit offsets is desired, the int64_t API
(functions with 64 suffix without underscore, notablly mpg123_reader64()) can be used since
API version 48 (mpg123 1.32).
When in doubt, use the explicit 64 bit functions and avoid off_t in the API. You can define
MPG123_PORTABLE_API to ensure that. That being said, if you and your compiler do not have
problems with the concept of off_t, just use the normal API and be happy. Both 32 and 64
bit versions will be present where appropriate.
*/
/** \page lfs Handling of large file offsets
*
* When client code defines _FILE_OFFSET_BITS, it wants non-default large file
* support, and thus functions with added suffix (mpg123_open_64). The default
* library build provides wrapper and alias functions to accomodate client code
* variations (dual-mode library like glibc).
*
* Client code can definie MPG123_NO_LARGENAME and MPG123_LARGESUFFIX,
* respectively, for disabling or enforcing the suffixes. You should *not* do
* this, though, unless you *really* want to deal with symbol ABI yourself.
* If explicit usage of 64 bit offsets is desired, the int64_t API
* consisting of functions with 64 suffix without underscore, notably
* mpg123_reader64(), can be used since API version 48 (mpg123 1.32). A matching
* mpg123_open64(), stripped-down mpg123_open_handle_64() is present since API
* version 49 (mpg123 1.33).
*
* When in doubt, use the explicit 64 bit functions and avoid off_t in the API.
* You can define MPG123_PORTABLE_API to ensure that. That being said, if you
* and your compiler do not have problems with the concept of off_t, just use
* the normal AP like the I/O API of the standard C library. Both 32 and 64 bit
* versions of functions will be present where appropriate.
*
* If your toolchain enforces _FILE_OFFSET_BITS also during build of libmpg123,
* only that setting will be supported for client code.
*/
#ifndef MPG123_PORTABLE_API
/*
Now, the renaming of large file aware functions.
By default, it appends underscore _FILE_OFFSET_BITS (so, mpg123_seek_64 for mpg123_seek), if _FILE_OFFSET_BITS is defined. You can force a different suffix via MPG123_LARGESUFFIX (that must include the underscore), or you can just disable the whole mess by defining MPG123_NO_LARGENAME.
/** \page lfs_names Renaming of functions for largefile support
*
* Now, the renaming of large file aware functions.
* By default, it appends underscore _FILE_OFFSET_BITS (so, mpg123_seek_64() for mpg123_seek()),
* if _FILE_OFFSET_BITS is defined. These are the affected API functions:
*
* - mpg123_open_fixed()
* - mpg123_open()
* - mpg123_open_fd()
* - mpg123_open_handle()
* - mpg123_framebyframe_decode()
* - mpg123_decode_frame()
* - mpg123_tell()
* - mpg123_tellframe()
* - mpg123_tell_stream()
* - mpg123_seek()
* - mpg123_feedseek()
* - mpg123_seek_frame()
* - mpg123_timeframe()
* - mpg123_index()
* - mpg123_set_index()
* - mpg123_position()
* - mpg123_length()
* - mpg123_framelength()
* - mpg123_set_filesize()
* - mpg123_replace_reader()
* - mpg123_replace_reader_handle()
* - mpg123_framepos()
*/
#if (!defined MPG123_NO_LARGENAME) && ((defined _FILE_OFFSET_BITS) || (defined MPG123_LARGESUFFIX))
@@ -142,6 +198,8 @@ typedef ssize_t mpg123_ssize_t;
#endif /* largefile hackery */
#endif
/** @} */
#ifdef __cplusplus
extern "C" {
#endif
@@ -774,7 +832,7 @@ MPG123_EXPORT int mpg123_open_fixed(mpg123_handle *mh, const char *path
* UTF-8, which also fits any sane modern install of Unix-like systems.
*
* \param mh handle
* \param path filesystem
* \param path filesystem path
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_open(mpg123_handle *mh, const char *path);
@@ -786,17 +844,63 @@ MPG123_EXPORT int mpg123_open(mpg123_handle *mh, const char *path);
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_open_fd(mpg123_handle *mh, int fd);
#endif
/** Use an opaque handle as bitstream input. This works only with the
* replaced I/O from mpg123_replace_reader_handle() or mpg123_reader64()!
* mpg123_close() will call the cleanup callback for your non-NULL
* handle (if you gave one).
* Note that this used to be usable with MPG123_PORTABLE_API defined in
* mpg123 1.32.x and was in fact the only entry point for handle I/O.
* Since mpg123 1.33.0 and API version 49, there is
* mpg123_open_handle64() for the portable case and has to be used
* instead of this function here, even if it _would_ work just fine,
* the inclusion of a largefile-renamed symbol in the portable set was wrong.
*
* \param mh handle
* \param iohandle your handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_open_handle(mpg123_handle *mh, void *iohandle);
#endif
/** Open and prepare to decode the specified file by filesystem path.
* This works exactly like mpg123_open() in modern libmpg123, see there
* for more description. This name is not subject to largefile symbol renaming.
* You can also use it with MPG123_PORTABLE_API.
*
* \param mh handle
* \param path filesystem path of your resource
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_open64(mpg123_handle *mh, const char *path);
/** Open a simple MPEG file with fixed properties.
* This is the same as mpg123_open_fixed(), just with a stable
* symbol name for int64_t portable API.
*
* \param mh handle
* \param path filesystem path (see mpg123_open())
* \param channels allowed channel count, either 1 (MPG123_MONO) or
* 2 (MPG123_STEREO), or bitwise or of them, but then you're halfway back to
* calling mpg123_format() again;-)
* \param encoding a definite encoding from enum mpg123_enc_enum
* or a bitmask like for mpg123_format(), defeating the purpose somewhat
*/
MPG123_EXPORT int mpg123_open_fixed64(mpg123_handle *mh, const char *path
, int channels, int encoding);
/** Use an opaque handle as bitstream input. This works only with the
* replaced I/O from mpg123_reader64()!
* mpg123_close() will call the cleanup callback for your non-NULL
* handle (if you gave one).
* This is a simplified variant of mpg123_open_handle() that only
* supports the int64_t API, available with MPG123_PORTABLE_API.
*
* \param mh handle
* \param iohandle your handle
* \return MPG123_OK on success
*/
MPG123_EXPORT int mpg123_open_handle64(mpg123_handle *mh, void *iohandle);
/** Open a new bitstream and prepare for direct feeding
* This works together with mpg123_decode(); you are responsible for reading and feeding the input bitstream.
@@ -1258,6 +1362,7 @@ MPG123_EXPORT int mpg123_eq2( mpg123_handle *mh
/** Set a range of equalizer bands
* \param channel Can be #MPG123_LEFT, #MPG123_RIGHT or
* #MPG123_LEFT|#MPG123_RIGHT for both.
* \param mh handle
* \param a The first equalizer band to set (from 0 to 31)
* \param b The last equalizer band to set (from 0 to 31)
* \param factor The (linear) adjustment factor, 1 being neutral.
@@ -1267,6 +1372,7 @@ MPG123_EXPORT int mpg123_eq_bands( mpg123_handle *mh
, int channel, int a, int b, double factor );
/** Change a range of equalizer bands
* \param mh handle
* \param channel Can be #MPG123_LEFT, #MPG123_RIGHT or
* #MPG123_LEFT|#MPG123_RIGHT for both.
* \param a The first equalizer band to change (from 0 to 31)
@@ -2218,7 +2324,8 @@ MPG123_EXPORT int mpg123_replace_reader_handle( mpg123_handle *mh
/** Set up portable read functions on an opaque handle.
* The handle is a void pointer, so you can pass any data you want...
* mpg123_open_handle() is the call you make to use the I/O defined here.
* mpg123_open64() (since API 49) or mpg123_open_handle() is the call you make
* to use the I/O defined here.
* There is no fallback to internal read/seek here.
* Note: As it would be troublesome to mess with this while having a file open,
* this mpg123_close() is implied here.

View File

@@ -20,7 +20,7 @@
*/
#define OUT123_API_VERSION 5
/** library patch level at client build time */
#define OUT123_PATCHLEVEL 1
#define OUT123_PATCHLEVEL 2
/* We only need size_t definition. */
#include <stddef.h>

View File

@@ -1112,7 +1112,7 @@ void syn123_be2host(void *buf, size_t samplesize, size_t samplecount);
// anywhere, also to avoid using non-standard types like ssize_t.
#if !defined(SYN123_PORTABLE_API) && !defined(SYN123_NO_LARGEFUNC)
/* A little hack to help MSVC not having ssize_t, duplicated in internal header. */
/** A little hack to help MSVC not having ssize_t, duplicated in internal header. */
#ifdef _MSC_VER
#include <stddef.h>
typedef ptrdiff_t syn123_ssize_t;

View File

@@ -341,7 +341,8 @@ int INT123_do_layer2(mpg123_handle *fr)
if(fr->jsbound > fr->II_sblimit)
{
fprintf(stderr, "Truncating stereo boundary to sideband limit.\n");
if(NOQUIET)
error("Truncating stereo boundary to sideband limit.");
fr->jsbound=fr->II_sblimit;
}

View File

@@ -15,9 +15,7 @@
#define FORCE_ACCURATE
#include "../common/sample.h"
#include "parse.h"
#ifndef PORTABLE_API
#include "lfs_wrap.h"
#endif
#include "../common/debug.h"
@@ -559,18 +557,9 @@ double attribute_align_arg mpg123_geteq2(mpg123_handle *mh, int channel, int ban
return mpg123_geteq(mh, channel, band);
}
#ifndef PORTABLE_API
#ifdef FORCED_OFF_64
// Only _64 symbols for a system-wide enforced _FILE_OFFSET_BITS=64.
#define mpg123_open mpg123_open_64
#define mpg123_open_fixed mpg123_open_fixed_64
#define mpg123_open_fd mpg123_open_fd_64
#define mpg123_open_handle mpg123_open_handle_64
#endif
/* plain file access, no http! */
int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
// LFS wrapper code is so agnostic to it all now that internal I/O is portable
// as long as you do not mix in off_t API.
int attribute_align_arg mpg123_open64(mpg123_handle *mh, const char *path)
{
if(mh == NULL) return MPG123_BAD_HANDLE;
@@ -585,6 +574,24 @@ int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
return ret;
}
#ifndef PORTABLE_API
#ifdef FORCED_OFF_64
// Only _64 symbols for a system-wide enforced _FILE_OFFSET_BITS=64.
#define mpg123_open mpg123_open_64
#define mpg123_open_fixed mpg123_open_fixed_64
#define mpg123_open_fd mpg123_open_fd_64
#define mpg123_open_handle mpg123_open_handle_64
#endif
// This now is agnostic to off_t choice, but still subject to renaming
// for legacy reasons.
int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
{
return mpg123_open64(mh, path);
}
#endif // PORTABLE_API
// The convenience function mpg123_open_fixed() wraps over acual mpg123_open
// and hence needs to have the exact same code in lfs_wrap.c. The flesh is
// in INT123_open_fixed_pre() and INT123_open_fixed_post(), wich are only defined here.
@@ -624,17 +631,28 @@ static int INT123_open_fixed_post(mpg123_handle *mh, int channels, int encoding)
return err;
}
int attribute_align_arg mpg123_open_fixed( mpg123_handle *mh, const char *path
int attribute_align_arg mpg123_open_fixed64( mpg123_handle *mh, const char *path
, int channels, int encoding )
{
int err = INT123_open_fixed_pre(mh, channels, encoding);
if(err == MPG123_OK)
err = mpg123_open(mh, path);
err = mpg123_open64(mh, path);
if(err == MPG123_OK)
err = INT123_open_fixed_post(mh, channels, encoding);
return err;
}
#ifndef PORTABLE_API
// Only to have the modern offset-agnostic open under a fixed name.
int attribute_align_arg mpg123_open_fixed( mpg123_handle *mh, const char *path
, int channels, int encoding )
{
return mpg123_open_fixed64(mh, path, channels, encoding);
}
// Won't define a 'portable' variant of this, as I cannot guess
// properties of the handed-in fd, which in theory, on specific platforms,
// could not support large files.
int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd)
{
if(mh == NULL) return MPG123_BAD_HANDLE;
@@ -650,21 +668,33 @@ int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd)
}
#endif // PORTABLE_API
// Only works with int64 reader setup.
int attribute_align_arg mpg123_open_handle64(mpg123_handle *mh, void *iohandle)
{
if(mh == NULL) return MPG123_BAD_HANDLE;
mpg123_close(mh);
return INT123_open_stream_handle(mh, iohandle);
}
#ifndef PORTABLE_API
// Change from 1.32: No largefile-renamed symbols in a library with strict
// portable API.
// I allow that breaking change since this is far from a standard libmpg123 build.
int attribute_align_arg mpg123_open_handle(mpg123_handle *mh, void *iohandle)
{
if(mh == NULL) return MPG123_BAD_HANDLE;
mpg123_close(mh);
int ret;
#ifndef PORTABLE_API
ret = INT123_wrap_open( mh, iohandle, NULL, -1
, mh->p.timeout, mh->p.flags & MPG123_QUIET );
iohandle = ret == LFS_WRAP_NONE ? iohandle : mh->wrapperdata;
if(ret >= 0)
#endif
ret = INT123_open_stream_handle(mh, iohandle);
return ret;
}
#endif
int attribute_align_arg mpg123_open_feed(mpg123_handle *mh)
{

View File

@@ -456,11 +456,11 @@ out123_open(out123_handle *ao, const char* driver, const char* device)
/* Now loop over the list of possible modules to find one that works. */
char *toksave = NULL;
nextname = strtok_r(modnames, ",", &toksave);
nextname = INT123_compat_strtok(modnames, ",", &toksave);
while(!ao->open && nextname)
{
char *curname = nextname;
nextname = strtok_r(NULL, ",", &toksave);
nextname = INT123_compat_strtok(NULL, ",", &toksave);
check_output_module(ao, curname, device, !nextname);
if(ao->open)
{

View File

@@ -172,7 +172,7 @@ static int get_formats_win32(out123_handle *ao)
int ret = 0;
UINT dev_id = dev_select(ao);
MMRESULT mr = waveOutGetDevCaps(dev_id, &caps, sizeof(caps));
MMRESULT mr = waveOutGetDevCapsA(dev_id, &caps, sizeof(caps));
if(mr != MMSYSERR_NOERROR)
return 0; /* no formats? */
@@ -367,7 +367,7 @@ static int enumerate_win32( out123_handle *ao, int (*store_device)(void *devlist
for(i = 0; i < devices; i++){
memset(id, 0, sizeof(id));
memset(&caps, 0, sizeof(caps));
mr = waveOutGetDevCaps(i, &caps, sizeof(caps));
mr = waveOutGetDevCapsA(i, &caps, sizeof(caps));
if (mr != MMSYSERR_NOERROR) {
switch(mr) {
case MMSYSERR_BADDEVICEID:

View File

@@ -59,6 +59,7 @@ size_t utf8outstr(char **dest, const char *source, int to_terminal);
// If count is >= 0, it is used instead of strlen(source), enabling
// processing of data without closing zero byte.
// Returns 0 if all went well, as do the others following.
// On error, the dest memory is freed and the pointer nulled.
int unknown2utf8(char **dest, const char *source, int count);
// Wrapper around the above for printing the string to some stream.
// Return value is directly from fprintf or also -1 if there was trouble

View File

@@ -364,7 +364,11 @@ int main(int argc, char **argv)
int i, result;
mpg123_handle* m;
#if defined(WANT_WIN32_UNICODE)
win32_cmdline_utf8(&argc,&argv);
if(win32_cmdline_utf8(&argc,&argv) != 0)
{
error("Cannot convert command line to UTF8!");
return 1;
}
#endif
progname = argv[0];
@@ -428,9 +432,9 @@ int main(int argc, char **argv)
mpg123_delete(m);
mpg123_exit();
if(errors) error1("Encountered %i errors along the way.", errors);
return errors != 0;
#if defined(WANT_WIN32_UNICODE)
win32_cmdline_free(argc,argv);
#endif
if(errors) error1("Encountered %i errors along the way.", errors);
return errors != 0;
}

View File

@@ -1431,9 +1431,17 @@ int main(int sys_argc, char ** sys_argv)
print_outstr(stderr, filename, 0, stderr_is_term);
fprintf(stderr, " ...\n");
if(filept->htd.icy_name.fill)
fprintf(stderr, "ICY-NAME: %s\n", filept->htd.icy_name.p);
{
fprintf(stderr, "ICY-NAME: ");
print_outstr(stderr, filept->htd.icy_name.p, 1, stderr_is_term);
fprintf(stderr, "\n");
}
if(filept->htd.icy_url.fill)
fprintf(stderr, "ICY-URL: %s\n", filept->htd.icy_url.p);
{
fprintf(stderr, "ICY-URL: ");
print_outstr(stderr, filept->htd.icy_url.p, 1, stderr_is_term);
fprintf(stderr, "\n");
}
}
#if !defined(GENERIC)
{
@@ -1515,7 +1523,9 @@ int main(int sys_argc, char ** sys_argv)
fprintf(stderr, "This was a Frankenstein track.\n");
position_info(mh, 0, ao, NULL, NULL, &secs, NULL, NULL, NULL);
fprintf(stderr,"[%d:%02d] Decoding of %s finished.\n", (int)(secs / 60), ((int)secs) % 60, filename);
fprintf(stderr,"[%d:%02d] Decoding of ", (int)(secs / 60), ((int)secs) % 60);
print_outstr(stderr, filename, 0, stderr_is_term);
fprintf(stderr," finished.\n");
}
else if(param.verbose) fprintf(stderr, "\n");

View File

@@ -34,6 +34,14 @@
enum playlist_type { UNKNOWN = 0, M3U, PLS, NO_LIST };
enum playflag
{
PL_IS_UTF8 = 1 // if we really know the contents are UTF-8-encooded
, PL_HIT_END = 2
, PL_STDIN_USED = 4 // If the playlist itself or an input file was '-' (stdin not usable for terminal.).
, PL_NO_RANDOM = 8
};
typedef struct listitem
{
char* url; /* the filename */
@@ -56,10 +64,7 @@ typedef struct playlist_struct
mpg123_string linebuf;
mpg123_string dir;
enum playlist_type type;
int is_utf8; /* if we really know the contents are UTF-8-encooded */
int hit_end;
// If the playlist itself or an input file was '-' (stdin not usable for terminal.).
int stdin_used;
unsigned int flags;
} playlist_struct;
/* one global instance... add a pointer to this to every function definition and you have OO-style... */
@@ -97,7 +102,7 @@ void prepare_playlist(int argc, char** argv, int args_utf8, int *is_utf8)
mpg123_free_string(&pl.linebuf);
mpg123_free_string(&pl.dir);
if(is_utf8)
*is_utf8 = pl.is_utf8;
*is_utf8 = (pl.flags & PL_IS_UTF8) != 0;
}
/* Return a random number >= 0 and < n */
@@ -142,9 +147,9 @@ char *get_next_file(void)
}
else
{
/* Handle looping first, but only if there is a random track selection
presently active (see playlist_jump() for interaction). */
if(!(pl.num && ((pl.loop > 0 && --pl.loop) || pl.loop < 0)))
// Handle looping first, but only if there is a random track selection
// Also applies to continue mode.
if(!(pl.num && ((pl.loop > 0 && --pl.loop) || pl.loop < 0)) && !(pl.flags & PL_NO_RANDOM))
{
/* Randomly select the next track. */
do /* limiting randomness: don't repeat too early */
@@ -157,6 +162,7 @@ char *get_next_file(void)
newitem = &pl.list[pl.pos];
pl.num = pl.pos+1;
pl.flags &= ~PL_NO_RANDOM; // The random blocking works only once.
}
/* "-" is STDIN, "" is dumb, NULL is nothing */
@@ -168,7 +174,7 @@ char *get_next_file(void)
}
else
{
pl.hit_end = TRUE;
pl.flags |= PL_HIT_END;
return NULL;
}
}
@@ -179,7 +185,7 @@ size_t playlist_pos(size_t *total, long *loop)
*total = pl.fill;
if(loop)
*loop = pl.loop;
return pl.hit_end ? pl.fill+1 : pl.num;
return pl.flags & PL_HIT_END ? pl.fill+1 : pl.num;
}
void playlist_jump(mpg123_ssize_t incr)
@@ -286,23 +292,23 @@ static void init_playlist(void)
pl.fill = 0;
pl.pos = 0;
pl.num = 0;
if(APPFLAG(MPG123APP_CONTINUE) && param.listentry > 0)
pl.pos = param.listentry - 1;
pl.list = NULL;
pl.alloc_step = 10;
mpg123_init_string(&pl.dir);
mpg123_init_string(&pl.linebuf);
pl.type = UNKNOWN;
pl.is_utf8 = FALSE;
pl.hit_end = FALSE;
pl.flags = 0;
pl.loop = param.loop;
pl.stdin_used = FALSE;
if(APPFLAG(MPG123APP_CONTINUE) && param.listentry > 0)
{
pl.pos = param.listentry - 1;
pl.flags |= PL_NO_RANDOM; // Skip random selection for first track.
}
}
int playlist_stdin(void)
{
return pl.stdin_used;
return (pl.flags & PL_STDIN_USED) != 0;
}
/*
@@ -314,7 +320,10 @@ static int add_next_file (int argc, char *argv[], int args_utf8)
{
int firstline = 0;
pl.is_utf8 = args_utf8;
if(args_utf8)
pl.flags |= PL_IS_UTF8;
else
pl.flags &= ~PL_IS_UTF8;
/* hack for url that has been detected as track, not playlist */
if(pl.type == NO_LIST) return 0;
@@ -343,7 +352,7 @@ static int add_next_file (int argc, char *argv[], int args_utf8)
if (param.listname || pl.file)
{
size_t line_offset = 0;
pl.is_utf8 = 0; // Playlist files in env encoding (HTTP lists should be ASCII-clean).
pl.flags &= ~PL_IS_UTF8; // Playlist files in env encoding (HTTP lists should be ASCII-clean).
if(!pl.file)
{
pl.file = stream_open(param.listname);
@@ -352,7 +361,7 @@ static int add_next_file (int argc, char *argv[], int args_utf8)
firstline = 1; /* just opened */
if(pl.file->fd == STDIN_FILENO)
{
pl.stdin_used = TRUE;
pl.flags |= PL_STDIN_USED;
param.listname = NULL;
}
}
@@ -393,7 +402,7 @@ static int add_next_file (int argc, char *argv[], int args_utf8)
}
}
char *ptmp = NULL;
outstr(&ptmp, pl.file->htd.content_type.p, 0, stderr_is_term);
outstr(&ptmp, pl.file->htd.content_type.p, 1, stderr_is_term);
error1( "Unknown playlist MIME type %s; maybe "PACKAGE_NAME
" can support it in future if you report this to the maintainer."
, PSTR(ptmp) );
@@ -671,7 +680,7 @@ static int add_to_playlist(char* new_entry, char freeit)
if(pl.fill < pl.size)
{
if(!strcmp(new_entry, "-") || !strcmp(new_entry, "/dev/stdin"))
pl.stdin_used = TRUE;
pl.flags |= PL_STDIN_USED;
pl.list[pl.fill].freeit = freeit;
pl.list[pl.fill].url = new_entry;
pl.list[pl.fill].playcount = 0;

View File

@@ -317,6 +317,17 @@ static int stream_parse_headers(struct stream *sd, mpg123_string *location)
{
break; // This is the content separator line.
}
{ // Convert from unknown/ASCII encoding to UTF-8. Play safe.
char *buf = NULL;
if(unknown2utf8(&buf, line.p, -1))
{
error("failed converting HTTP header line");
continue;
}
// Avoiding extra allocation here would be nice. mpg123_adopt_string()?
mpg123_set_string(&line, buf);
free(buf);
}
// React to HTTP error codes, but do not enforce an OK being sent as Shoutcast
// only produces very minimal headers, not even a HTTP response code.
// Well, ICY 200 OK could be there, but then we got other headers to know

View File

@@ -15,11 +15,11 @@
// only single spaces as separator to ease parsing by build scripts
#define MPG123_MAJOR 1
#define MPG123_MINOR 32
#define MPG123_PATCH 10
#define MPG123_MINOR 33
#define MPG123_PATCH 0
// Don't get too wild with that to avoid confusing m4. No brackets.
// Also, it should fit well into a sane file name for the tarball.
#define MPG123_SUFFIX ""
#define MPG123_SUFFIX "-dev+20250525022201"
#define MPG123_VERSION_CAT_REALLY(a, b, c) #a "." #b "." #c
#define MPG123_VERSION_CAT(a, b, c) MPG123_VERSION_CAT_REALLY(a, b, c)

View File

@@ -22,6 +22,7 @@ void __cdecl __declspec(dllimport) __wgetmainargs (
int win32_cmdline_utf8(int * argc, char *** argv)
{
int argcounter;
int nargc;
wchar_t **argv_wide;
wchar_t **env;
char *argvptr;
@@ -31,9 +32,21 @@ int win32_cmdline_utf8(int * argc, char *** argv)
if(argv == NULL || argc == NULL) return -1;
startup.newmode = 0;
__wgetmainargs(argc, &argv_wide,&env,1, &startup);
nargc = -1;
argv_wide = NULL;
env = NULL;
__wgetmainargs(&nargc, &argv_wide,&env,1, &startup);
if (nargc == -1 || argv_wide == NULL || env == NULL) {
error("Cannot allocate memory for wide command line.");
return -1;
}
*argc = nargc;
*argv = (char **)calloc(sizeof (char *), *argc);
if(*argv == NULL){ error("Cannot allocate memory for command line."); return -1; }
if(*argv == NULL)
{
error("Cannot allocate memory for UTF-8 command line.");
return -1;
}
for(argcounter = 0; argcounter < *argc; argcounter++)
{