/src/ffmpeg/libavutil/error.c
Line | Count | Source |
1 | | /* |
2 | | * This file is part of FFmpeg. |
3 | | * |
4 | | * FFmpeg is free software; you can redistribute it and/or |
5 | | * modify it under the terms of the GNU Lesser General Public |
6 | | * License as published by the Free Software Foundation; either |
7 | | * version 2.1 of the License, or (at your option) any later version. |
8 | | * |
9 | | * FFmpeg is distributed in the hope that it will be useful, |
10 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | | * Lesser General Public License for more details. |
13 | | * |
14 | | * You should have received a copy of the GNU Lesser General Public |
15 | | * License along with FFmpeg; if not, write to the Free Software |
16 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | | */ |
18 | | |
19 | | #undef _GNU_SOURCE |
20 | | #define _XOPEN_SOURCE 600 /* XSI-compliant version of strerror_r */ |
21 | | #include <stdio.h> |
22 | | #include <string.h> |
23 | | #include "config.h" |
24 | | #include "avstring.h" |
25 | | #include "error.h" |
26 | | #include "macros.h" |
27 | | |
28 | | #define AVERROR_INPUT_AND_OUTPUT_CHANGED (AVERROR_INPUT_CHANGED | AVERROR_OUTPUT_CHANGED) |
29 | | |
30 | | #define AVERROR_LIST(E, E2) \ |
31 | | E(BSF_NOT_FOUND, "Bitstream filter not found") \ |
32 | | E(BUG, "Internal bug, should not have happened") \ |
33 | | E2(BUG2, BUG, "Internal bug, should not have happened") \ |
34 | | E(BUFFER_TOO_SMALL, "Buffer too small") \ |
35 | | E(DECODER_NOT_FOUND, "Decoder not found") \ |
36 | | E(DEMUXER_NOT_FOUND, "Demuxer not found") \ |
37 | | E(ENCODER_NOT_FOUND, "Encoder not found") \ |
38 | | E(EOF, "End of file") \ |
39 | | E(EXIT, "Immediate exit requested") \ |
40 | | E(EXTERNAL, "Generic error in an external library") \ |
41 | | E(FILTER_NOT_FOUND, "Filter not found") \ |
42 | | E(INPUT_CHANGED, "Input changed") \ |
43 | | E(INVALIDDATA, "Invalid data found when processing input") \ |
44 | | E(MUXER_NOT_FOUND, "Muxer not found") \ |
45 | | E(OPTION_NOT_FOUND, "Option not found") \ |
46 | | E(OUTPUT_CHANGED, "Output changed") \ |
47 | | E(PATCHWELCOME, "Not yet implemented in FFmpeg, patches welcome") \ |
48 | | E(PROTOCOL_NOT_FOUND, "Protocol not found") \ |
49 | | E(STREAM_NOT_FOUND, "Stream not found") \ |
50 | | E(UNKNOWN, "Unknown error occurred") \ |
51 | | E(EXPERIMENTAL, "Experimental feature") \ |
52 | | E(INPUT_AND_OUTPUT_CHANGED, "Input and output changed") \ |
53 | | E(HTTP_BAD_REQUEST, "Server returned 400 Bad Request") \ |
54 | | E(HTTP_UNAUTHORIZED, "Server returned 401 Unauthorized (authorization failed)") \ |
55 | | E(HTTP_FORBIDDEN, "Server returned 403 Forbidden (access denied)") \ |
56 | | E(HTTP_NOT_FOUND, "Server returned 404 Not Found") \ |
57 | | E(HTTP_TOO_MANY_REQUESTS, "Server returned 429 Too Many Requests") \ |
58 | | E(HTTP_OTHER_4XX, "Server returned 4XX Client Error, but not one of 40{0,1,3,4}") \ |
59 | | E(HTTP_SERVER_ERROR, "Server returned 5XX Server Error reply") \ |
60 | | |
61 | | #define STRERROR_LIST(E) \ |
62 | | E(E2BIG, "Argument list too long") \ |
63 | | E(EACCES, "Permission denied") \ |
64 | | E(EAGAIN, "Resource temporarily unavailable") \ |
65 | | E(EBADF, "Bad file descriptor") \ |
66 | | E(EBUSY, "Device or resource busy") \ |
67 | | E(ECHILD, "No child processes") \ |
68 | | E(EDEADLK, "Resource deadlock avoided") \ |
69 | | E(EDOM, "Numerical argument out of domain") \ |
70 | | E(EEXIST, "File exists") \ |
71 | | E(EFAULT, "Bad address") \ |
72 | | E(EFBIG, "File too large") \ |
73 | | E(EILSEQ, "Illegal byte sequence") \ |
74 | | E(EINTR, "Interrupted system call") \ |
75 | | E(EINVAL, "Invalid argument") \ |
76 | | E(EIO, "I/O error") \ |
77 | | E(EISDIR, "Is a directory") \ |
78 | | E(EMFILE, "Too many open files") \ |
79 | | E(EMLINK, "Too many links") \ |
80 | | E(ENAMETOOLONG, "File name too long") \ |
81 | | E(ENFILE, "Too many open files in system") \ |
82 | | E(ENODEV, "No such device") \ |
83 | | E(ENOENT, "No such file or directory") \ |
84 | | E(ENOEXEC, "Exec format error") \ |
85 | | E(ENOLCK, "No locks available") \ |
86 | | E(ENOMEM, "Cannot allocate memory") \ |
87 | | E(ENOSPC, "No space left on device") \ |
88 | | E(ENOSYS, "Function not implemented") \ |
89 | | E(ENOTDIR, "Not a directory") \ |
90 | | E(ENOTEMPTY, "Directory not empty") \ |
91 | | E(ENOTTY, "Inappropriate I/O control operation") \ |
92 | | E(ENXIO, "No such device or address") \ |
93 | | E(EPERM, "Operation not permitted") \ |
94 | | E(EPIPE, "Broken pipe") \ |
95 | | E(ERANGE, "Result too large") \ |
96 | | E(EROFS, "Read-only file system") \ |
97 | | E(ESPIPE, "Illegal seek") \ |
98 | | E(ESRCH, "No such process") \ |
99 | | E(EXDEV, "Cross-device link") \ |
100 | | |
101 | | enum { |
102 | | #define OFFSET(CODE, DESC) \ |
103 | | ERROR_ ## CODE ## _OFFSET, \ |
104 | | ERROR_ ## CODE ## _END_OFFSET = ERROR_ ## CODE ## _OFFSET + sizeof(DESC) - 1, |
105 | | #define NOTHING(CODE, CODE2, DESC) |
106 | | AVERROR_LIST(OFFSET, NOTHING) |
107 | | #if !HAVE_STRERROR_R |
108 | | STRERROR_LIST(OFFSET) |
109 | | #endif |
110 | | ERROR_LIST_SIZE |
111 | | }; |
112 | | |
113 | | #define STRING(CODE, DESC) DESC "\0" |
114 | | static const char error_stringtable[ERROR_LIST_SIZE] = |
115 | | AVERROR_LIST(STRING, NOTHING) |
116 | | #if !HAVE_STRERROR_R |
117 | | STRERROR_LIST(STRING) |
118 | | #endif |
119 | | ; |
120 | | |
121 | | static const struct ErrorEntry { |
122 | | int num; |
123 | | unsigned offset; |
124 | | } error_entries[] = { |
125 | | #define ENTRY(CODE, DESC) { .num = AVERROR_ ## CODE, .offset = ERROR_ ## CODE ## _OFFSET }, |
126 | | #define ENTRY2(CODE, CODE2, DESC) { .num = AVERROR_ ## CODE, .offset = ERROR_ ## CODE2 ## _OFFSET }, |
127 | | AVERROR_LIST(ENTRY, ENTRY2) |
128 | | #if !HAVE_STRERROR_R |
129 | | #undef ENTRY |
130 | | #define ENTRY(CODE, DESC) { .num = AVERROR(CODE), .offset = ERROR_ ## CODE ## _OFFSET }, |
131 | | STRERROR_LIST(ENTRY) |
132 | | #endif |
133 | | }; |
134 | | |
135 | | int av_strerror(int errnum, char *errbuf, size_t errbuf_size) |
136 | 0 | { |
137 | 0 | for (size_t i = 0; i < FF_ARRAY_ELEMS(error_entries); ++i) { |
138 | 0 | if (errnum == error_entries[i].num) { |
139 | 0 | av_strlcpy(errbuf, error_stringtable + error_entries[i].offset, errbuf_size); |
140 | 0 | return 0; |
141 | 0 | } |
142 | 0 | } |
143 | 0 | #if HAVE_STRERROR_R |
144 | 0 | int ret = AVERROR(strerror_r(AVUNERROR(errnum), errbuf, errbuf_size)); |
145 | | #else |
146 | | int ret = -1; |
147 | | #endif |
148 | 0 | if (ret < 0) |
149 | 0 | snprintf(errbuf, errbuf_size, "Error number %d occurred", errnum); |
150 | |
|
151 | 0 | return ret; |
152 | 0 | } |