ref: c94b05ceb57399f55ddd31c51748bb5bf2f7835c
dir: /src/util.c/
/* * util.c. * Utility functions mostly related to logging. * * July 5, 1991 * Copyright 1991 Lance Norskog And Sundry Contributors * This source code is freely redistributable and may be used for * any purpose. This copyright notice must be maintained. * Lance Norskog And Sundry Contributors are not responsible for * the consequences of using this software. */ #include "sox_i.h" #include <assert.h> #include <string.h> #include <stdarg.h> void sox_output_message(FILE *file, const char *filename, const char *fmt, va_list ap) { char const * slash_pos = LAST_SLASH(filename); char const * base_name = slash_pos? slash_pos + 1 : filename; char const * dot_pos = strrchr(base_name, '.'); fprintf(file, "%.*s: ", dot_pos? dot_pos - base_name : -1, base_name); vfprintf(file, fmt, ap); } #undef sox_fail #undef sox_warn #undef sox_report #undef sox_debug #undef sox_debug_more #undef sox_debug_most #define SOX_MESSAGE_FUNCTION(name,level) \ void name(char const * fmt, ...) { \ va_list ap; \ va_start(ap, fmt); \ if (sox_globals.output_message_handler) \ (*sox_globals.output_message_handler)(level,sox_globals.subsystem,fmt,ap); \ va_end(ap); \ } SOX_MESSAGE_FUNCTION(sox_fail , 1) SOX_MESSAGE_FUNCTION(sox_warn , 2) SOX_MESSAGE_FUNCTION(sox_report, 3) SOX_MESSAGE_FUNCTION(sox_debug , 4) SOX_MESSAGE_FUNCTION(sox_debug_more , 5) SOX_MESSAGE_FUNCTION(sox_debug_most , 6) #undef SOX_MESSAGE_FUNCTION void sox_fail_errno(sox_format_t * ft, int sox_errno, const char *fmt, ...) { va_list args; ft->sox_errno = sox_errno; va_start(args, fmt); #ifdef HAVE_VSNPRINTF vsnprintf(ft->sox_errstr, sizeof(ft->sox_errstr), fmt, args); #else vsprintf(ft->sox_errstr, fmt, args); #endif va_end(args); ft->sox_errstr[255] = '\0'; } /* * sox_parsesamples * * Parse a string for # of samples. If string ends with a 's' * then the string is interpreted as a user calculated # of samples. * If string contains ':' or '.' or if it ends with a 't' then its * treated as an amount of time. This is converted into seconds and * fraction of seconds and then use the sample rate to calculate * # of samples. * Returns NULL on error, pointer to next char to parse otherwise. */ char const * sox_parsesamples(sox_rate_t rate, const char *str, sox_size_t *samples, int def) { int found_samples = 0, found_time = 0; int time = 0; long long_samples; float frac = 0; char const * end; char const * pos; sox_bool found_colon, found_dot; for (end = str; *end && strchr("0123456789:.ts", *end); ++end); if (end == str) return NULL; pos = strchr(str, ':'); found_colon = pos && pos < end; pos = strchr(str, '.'); found_dot = pos && pos < end; if (found_colon || found_dot || *(end-1) == 't') found_time = 1; else if (*(end-1) == 's') found_samples = 1; if (found_time || (def == 't' && !found_samples)) { *samples = 0; while(1) { if (str[0] != '.' && sscanf(str, "%d", &time) != 1) return NULL; *samples += time; while (*str != ':' && *str != '.' && *str != 0) str++; if (*str == '.' || *str == 0) break; /* Skip past ':' */ str++; *samples *= 60; } if (*str == '.') { if (sscanf(str, "%f", &frac) != 1) return NULL; } *samples *= rate; *samples += (rate * frac) + 0.5; return end; } if (found_samples || (def == 's' && !found_time)) { if (sscanf(str, "%ld", &long_samples) != 1) return NULL; *samples = long_samples; return end; } return NULL; } /*--------------------------------- Comments ---------------------------------*/ size_t num_comments(comments_t comments) { size_t result = 0; if (!comments) return 0; while (*comments++) ++result; return result; } void append_comment(comments_t * comments, char const * comment) { size_t n = num_comments(*comments); *comments = xrealloc(*comments, (n + 2) * sizeof(**comments)); assert(comment); (*comments)[n++] = xstrdup(comment); (*comments)[n] = 0; } void append_comments(comments_t * comments, char const * comment) { char * end; if (comment) { while ((end = strchr(comment, '\n'))) { size_t len = end - comment; char * c = xmalloc((len + 1) * sizeof(*c)); strncpy(c, comment, len); c[len] = '\0'; append_comment(comments, c); comment += len + 1; free(c); } if (*comment) append_comment(comments, comment); } } comments_t copy_comments(comments_t comments) { comments_t result = 0; if (comments) while (*comments) append_comment(&result, *comments++); return result; } void delete_comments(comments_t * comments) { comments_t p = *comments; if (p) while (*p) free(*p++); free(*comments); *comments = 0; } char * cat_comments(comments_t comments) { comments_t p = comments; size_t len = 0; char * result; if (p) while (*p) len += strlen(*p++) + 1; result = xcalloc(len? len : 1, sizeof(*result)); if ((p = comments) && *p) { strcpy(result, *p); while (*++p) strcat(strcat(result, "\n"), *p); } return result; } char const * find_comment(comments_t comments, char const * id) { size_t len = strlen(id); if (comments) for (;*comments; ++comments) if (!strncasecmp(*comments, id, len) && (*comments)[len] == '=') return *comments + len + 1; return NULL; }