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 0 : 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 0 : fputs("ERROR: ",stderr);
29 0 : fputs(prefix,stderr);
30 0 : fputs(" [File: ",stderr);
31 0 : fputs(file,stderr);
32 0 : fputs(", Function: ",stderr);
33 0 : fputs(func,stderr);
34 0 : fputs("] Errno: (",stderr);
35 0 : fputs(itoa(errno,itoa_buf,10),stderr);
36 0 : fputs(") ",stderr);
37 0 : fputs(strerror(errno),stderr);
38 0 : fputs("\n",stderr);
39 0 : }
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 : }
|