| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include "DFPlatform.h" |
| #include <DocFormats/DFError.h> |
| #include "DFCommon.h" |
| #include <assert.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| struct DFError { |
| size_t retainCount; |
| char *message; |
| }; |
| |
| void DFErrorSetPosix(DFError **error, int code) |
| { |
| DFErrorFormat(error,"%s",strerror(code)); |
| } |
| |
| void DFErrorVFormat(DFError **error, const char *format, va_list ap) |
| { |
| if (error == NULL) { |
| return; |
| } |
| |
| va_list ap2; |
| va_copy(ap2,ap); |
| size_t nchars = vsnprintf(NULL,0,format,ap2); |
| va_end(ap2); |
| |
| char *message = (char *)xmalloc(nchars+1); |
| |
| va_copy(ap2,ap); |
| vsnprintf(message,nchars+1,format,ap2); |
| va_end(ap2); |
| |
| if (*error != NULL) { |
| // Error object exists; replace the existing message |
| free((*error)->message); |
| (*error)->message = message; |
| } |
| else { |
| // Error object does not exist; create a new one |
| (*error) = (DFError *)xcalloc(1,sizeof(DFError)); |
| (*error)->retainCount = 1; |
| (*error)->message = message; |
| } |
| } |
| |
| void DFErrorFormat(DFError **error, const char *format, ...) |
| { |
| va_list ap; |
| va_start(ap,format); |
| DFErrorVFormat(error,format,ap); |
| va_end(ap); |
| } |
| |
| DFError *DFErrorRetain(DFError *error) |
| { |
| if (error == NULL) |
| return NULL; |
| error->retainCount++; |
| return error; |
| } |
| |
| void DFErrorRelease(DFError *error) |
| { |
| if (error == NULL) |
| return; |
| assert(error->retainCount > 0); |
| error->retainCount--; |
| if (error->retainCount == 0) { |
| free(error->message); |
| free(error); |
| } |
| } |
| |
| const char *DFErrorMessage(DFError **error) |
| { |
| if ((error == NULL) || (*error == NULL)) |
| return "Unknown error"; |
| else |
| return (*error)->message; |
| } |