Branch data Line data Source code
1 : : #include "rational.h"
2 : : #include <unistd.h>
3 : : #include <errno.h>
4 : : #include <stdarg.h>
5 : :
6 : : /**
7 : : * @brief Safely prints an error message with system error description to stderr
8 : : *
9 : : * @param prefix Custom message to prepend to the error (must not be NULL)
10 : : * @param file Source file name where the function was called (must not be NULL)
11 : : * @param func Name of the calling function (must not be NULL)
12 : : * @return void
13 : : *
14 : : * @note This function doesn't allocate memory dynamically and is safe to use
15 : : * in low-memory conditions
16 : : *
17 : : * @example
18 : : * serp("Failed to allocate memory"); <- NO EOL (\n)!
19 : : */
20 : 1 : void SERP(
21 : : const char *prefix,
22 : : const char *file,
23 : : const char *func)
24 : : {
25 : : /* Buffer for converting errno to string, size 32 is sufficient for max int */
26 : : char itoa_buf[32];
27 : :
28 : 1 : fputs("ERROR: ",stderr);
29 : 1 : fputs(prefix,stderr);
30 : 1 : fputs(" [File: ",stderr);
31 : 1 : fputs(file,stderr);
32 : 1 : fputs(", Function: ",stderr);
33 : 1 : fputs(func,stderr);
34 : 1 : fputs("] Errno: (",stderr);
35 : 1 : fputs(itoa(errno,itoa_buf,10),stderr);
36 : 1 : fputs(") ",stderr);
37 : 1 : fputs(strerror(errno),stderr);
38 : 1 : fputs("\n",stderr);
39 : 1 : }
40 : :
41 : : /**
42 : : * @brief Reports an error message with debug info to stderr
43 : : *
44 : : * This function generates a formatted error message with variable arguments and
45 : : * writes it directly to stderr without using dynamic memory allocation.
46 : : * Includes source location information and system error details.
47 : : *
48 : : * @param source_file Name of the source file where error occurred (must not be NULL)
49 : : * @param func_name Name of the function where error occurred (must not be NULL)
50 : : * @param line_num Line number where error occurred (must be positive)
51 : : * @param format Printf-style format string for the error message (must not be NULL)
52 : : * @param ... Variable arguments matching format specifiers
53 : : * @return void
54 : : *
55 : : * @note Maximum message length is limited by MAX_CHARACTERS
56 : : *
57 : : * @example
58 : : * REPORT(__FILE__, __func__, __LINE__, "Failed to allocate %d bytes", size);
59 : : */
60 : : __attribute__((format(printf,4,5)))
61 : 2 : void REPORT(
62 : : const char *source_file,
63 : : const char *func_name,
64 : : int line_num,
65 : : const char *format,
66 : : ...)
67 : : {
68 : : /* Buffers for message construction, zero-initialized for safety */
69 : 2 : char msg_buffer[MAX_CHARACTERS] = {0}; /* User message buffer */
70 : 2 : char final_buffer[MAX_CHARACTERS] = {0}; /* Complete error message */
71 : :
72 : : va_list args;
73 : 2 : va_start(args,format);
74 : 2 : vsnprintf(msg_buffer,sizeof(msg_buffer),format,args);
75 : 2 : va_end(args);
76 : :
77 : : /* Format complete error message with debug info and errno details */
78 : 4 : ssize_t len = snprintf(final_buffer,
79 : : sizeof(final_buffer),
80 : : "ERROR: %s:%s:%d %s Errno: %s (errno: %d)\n",
81 : : source_file,
82 : : func_name,
83 : : line_num,
84 : : msg_buffer,
85 : 2 : strerror(errno),
86 : 2 : errno
87 : : );
88 : :
89 : : /* Write message to stderr, handling potential buffer size limitations */
90 [ + - ]: 2 : if(len > 0)
91 : : {
92 : 2 : size_t write_size = sizeof(final_buffer);
93 : :
94 [ + - ]: 2 : if((size_t)len < sizeof(final_buffer))
95 : : {
96 : 2 : write_size = (size_t)len;
97 : : }
98 : :
99 : : /* Attempt to write error message */
100 [ - + ]: 2 : if(write(STDERR_FILENO,final_buffer,write_size) < 0)
101 : : {
102 : : /* Fallback error message if primary write fails */
103 : 0 : const char fallback_msg[] = "ERROR: Failed to write error message\n";
104 : :
105 [ # # ]: 0 : if(write(STDERR_FILENO,fallback_msg,sizeof(fallback_msg) - 1) < 0)
106 : : {
107 : 0 : return;
108 : : }
109 : : }
110 : : }
111 : : }
|