OMCompiler/Compiler/Util/omc_file_ext.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of OpenModelica. | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), | ||
| 5 | * c/o Linköpings universitet, Department of Computer and Information Science, | ||
| 6 | * SE-58183 Linköping, Sweden. | ||
| 7 | * | ||
| 8 | * All rights reserved. | ||
| 9 | * | ||
| 10 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR | ||
| 11 | * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. | ||
| 12 | * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES | ||
| 13 | * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL | ||
| 14 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 15 | * | ||
| 16 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) | ||
| 17 | * Public License (OSMC-PL) are obtained from OSMC, either from the above | ||
| 18 | * address, from the URLs: | ||
| 19 | * http://www.openmodelica.org or | ||
| 20 | * https://github.com/OpenModelica/ or | ||
| 21 | * http://www.ida.liu.se/projects/OpenModelica, | ||
| 22 | * and in the OpenModelica distribution. | ||
| 23 | * | ||
| 24 | * GNU AGPL version 3 is obtained from: | ||
| 25 | * https://www.gnu.org/licenses/licenses.html#GPL | ||
| 26 | * | ||
| 27 | * This program is distributed WITHOUT ANY WARRANTY; without | ||
| 28 | * even the implied warranty of MERCHANTABILITY or FITNESS | ||
| 29 | * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH | ||
| 30 | * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. | ||
| 31 | * | ||
| 32 | * See the full OSMC Public License conditions for more details. | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | #ifndef __OMC_FILE_H | ||
| 37 | #define __OMC_FILE_H | ||
| 38 | |||
| 39 | #include <stdio.h> | ||
| 40 | #include <gc.h> | ||
| 41 | #include <errno.h> | ||
| 42 | #include "ModelicaUtilities.h" | ||
| 43 | |||
| 44 | #include "util/omc_file.h" | ||
| 45 | |||
| 46 | typedef struct { | ||
| 47 | FILE* file /* the file */; | ||
| 48 | mmc_sint_t cnt /* reference count */; | ||
| 49 | const char* name /* the file name */; | ||
| 50 | } __OMC_FILE; | ||
| 51 | |||
| 52 | enum escape_t { | ||
| 53 | None=1, | ||
| 54 | C, | ||
| 55 | JSON, | ||
| 56 | XML | ||
| 57 | }; | ||
| 58 | |||
| 59 | enum whence_t { | ||
| 60 | OMC_SEEK_SET=1, | ||
| 61 | OMC_SEEK_CURRENT, | ||
| 62 | OMC_SEEK_END | ||
| 63 | }; | ||
| 64 | |||
| 65 | |||
| 66 | static inline void* om_file_new(void *fromID) | ||
| 67 | { | ||
| 68 |
2/2✓ Branch 0 taken 34114 times.
✓ Branch 1 taken 17364307 times.
|
17398421 | if (0==fromID) { |
| 69 | 34114 | __OMC_FILE *res = (__OMC_FILE*) GC_malloc(sizeof(__OMC_FILE)); | |
| 70 | 34114 | res->file = NULL; | |
| 71 | 34114 | res->cnt = 0; | |
| 72 | 34114 | res->name = "[no open file]"; | |
| 73 | #if defined(__OMC_FILE_DEBUG) | ||
| 74 | fprintf(stderr,"File.constructor: new %s\n", res->name); fflush(NULL); | ||
| 75 | #endif | ||
| 76 | 34114 | return res; | |
| 77 | } else { | ||
| 78 | 17364307 | ((__OMC_FILE*)fromID)->cnt++; /* Increase reference count */ | |
| 79 | #if defined(__OMC_FILE_DEBUG) | ||
| 80 | fprintf(stderr,"File.constructor: fromID: %s, %ld %p\n", ((__OMC_FILE*)fromID)->name, (long) ((__OMC_FILE*)fromID)->cnt, fromID); fflush(NULL); | ||
| 81 | #endif | ||
| 82 | 17364307 | return fromID; | |
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | 17398421 | static inline void om_file_free(__OMC_FILE *file) | |
| 87 | { | ||
| 88 |
2/2✓ Branch 0 taken 17364307 times.
✓ Branch 1 taken 34114 times.
|
17398421 | if (file->cnt /* reference count */) { |
| 89 | 17364307 | file->cnt--; | |
| 90 | 17364307 | return; | |
| 91 | } | ||
| 92 | #if defined(__OMC_FILE_DEBUG) | ||
| 93 | fprintf(stderr,"File.destructor: close:%s,%p,%p\n",file->name, file->file, file); fflush(NULL); | ||
| 94 | #endif | ||
| 95 | 34114 | fclose(file->file); | |
| 96 | 34114 | file->file = 0; | |
| 97 | 34114 | file->name = "[closed]"; | |
| 98 | 34114 | GC_free(file); | |
| 99 | } | ||
| 100 | |||
| 101 | 34114 | static inline void om_file_open(__OMC_FILE *file, const char *filename, int mode) | |
| 102 | { | ||
| 103 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34114 times.
|
34114 | if (file->file) { |
| 104 | #if defined(__OMC_FILE_DEBUG) | ||
| 105 | fprintf(stderr,"File.open: close :%s,%p,%p\n",file->name, file->file, file); fflush(NULL); | ||
| 106 | #endif | ||
| 107 | ✗ | fclose(file->file); | |
| 108 | } | ||
| 109 | #if defined(__APPLE_CC__)||defined(__MINGW32__)||defined(__MINGW64__) | ||
| 110 | if (mode == 1) { | ||
| 111 | file->file = omc_fopen(filename, "rb"); | ||
| 112 | } else { | ||
| 113 | omc_unlink(filename); | ||
| 114 | file->file = omc_fopen(filename, "wb"); | ||
| 115 | } | ||
| 116 | #else | ||
| 117 |
1/2✓ Branch 0 taken 34114 times.
✗ Branch 1 not taken.
|
68228 | file->file = fopen(filename, mode == 1 ? "rb" : "wb"); |
| 118 | #endif | ||
| 119 | 34114 | file->name = filename; | |
| 120 | #if defined(__OMC_FILE_DEBUG) | ||
| 121 | fprintf(stderr,"File.open: f:%s,%p,%p\n",file->name,file->file,file); fflush(NULL); | ||
| 122 | #endif | ||
| 123 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34114 times.
|
34114 | if (0 == file->file) { |
| 124 | ✗ | ModelicaFormatError("File.open: Failed to open file %s with mode %d: %s\n", filename, mode, strerror(errno)); | |
| 125 | } | ||
| 126 | 34114 | } | |
| 127 | |||
| 128 | 98596261 | static inline void om_file_write(__OMC_FILE *file,const char *data) | |
| 129 | { | ||
| 130 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 98596261 times.
|
98596261 | if (!file->file) { |
| 131 | ✗ | ModelicaFormatError("File.write: Failed to write to file: %s (not open)", file->name); | |
| 132 | } | ||
| 133 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 98596261 times.
|
98596261 | if (EOF == fputs(data, file->file)) { |
| 134 | ✗ | ModelicaFormatError("File.write: Failed to write to file: %s error: %s\n", file->name, strerror(errno)); | |
| 135 | } | ||
| 136 | 98596261 | } | |
| 137 | |||
| 138 | 7178808 | static inline void om_file_write_int(__OMC_FILE *file, int data, const char *format) | |
| 139 | { | ||
| 140 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7178808 times.
|
7178808 | if (!file->file) { |
| 141 | ✗ | ModelicaFormatError("File.writeInt: Failed to write to file: %s (not open)", file->name); | |
| 142 | } | ||
| 143 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7178808 times.
|
7178808 | if (EOF == fprintf(file->file, format, data)) { |
| 144 | ✗ | ModelicaFormatError("File.writeInt: Failed to write to file: %s error: %s\n", file->name, strerror(errno)); | |
| 145 | } | ||
| 146 | 7178808 | } | |
| 147 | |||
| 148 | 4628 | static inline void om_file_write_real(__OMC_FILE *file, double data, const char *format) | |
| 149 | { | ||
| 150 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4628 times.
|
4628 | if (!file->file) { |
| 151 | ✗ | ModelicaFormatError("File.writeReal: Failed to write to file: %s (not open)", file->name); | |
| 152 | } | ||
| 153 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4628 times.
|
4628 | if (EOF == fprintf(file->file, format, data)) { |
| 154 | ✗ | ModelicaFormatError("File.writeReal: Failed to write to file: %s error: %s\n", file->name, strerror(errno)); | |
| 155 | } | ||
| 156 | 4628 | } | |
| 157 | |||
| 158 | #define OMC_ERROR_WRITE() ModelicaFormatError("File.writeEscape: Failed to write to file %s: %s error: %s\n", file->name, (char *)file->file, strerror(errno)) | ||
| 159 | |||
| 160 | 9812286 | static inline void om_file_write_escape(__OMC_FILE *file, const char *data, enum escape_t escape) | |
| 161 | { | ||
| 162 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9812286 times.
|
9812286 | if (!file->file) { |
| 163 | ✗ | ModelicaFormatError("File.writeEscape: Failed to write to file: %s (not open)", file->name); | |
| 164 | } | ||
| 165 |
3/5✓ Branch 0 taken 213572 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7028474 times.
✓ Branch 3 taken 2570240 times.
✗ Branch 4 not taken.
|
9812286 | switch (escape) { |
| 166 | 213572 | case None: | |
| 167 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 213572 times.
|
213572 | if (EOF == fputs(data, file->file)) { |
| 168 | ✗ | ModelicaFormatError("File.writeEscape: Failed to write to file: %s error: %s\n", file->name, strerror(errno)); | |
| 169 | } | ||
| 170 | break; | ||
| 171 | case C: | ||
| 172 | ✗ | while (*data) { | |
| 173 | ✗ | if (*data == '\n') { | |
| 174 | ✗ | if (fputs("\\n", file->file) < 0) OMC_ERROR_WRITE(); | |
| 175 | ✗ | } else if (*data == '"') { | |
| 176 | ✗ | if (fputs("\\\"", file->file) < 0) OMC_ERROR_WRITE(); | |
| 177 | } else { | ||
| 178 | ✗ | if (putc(*data, file->file) < 0) OMC_ERROR_WRITE(); | |
| 179 | } | ||
| 180 | ✗ | data++; | |
| 181 | } | ||
| 182 | break; | ||
| 183 | case JSON: | ||
| 184 |
2/2✓ Branch 0 taken 142254130 times.
✓ Branch 1 taken 7028474 times.
|
149282604 | while (*data) { |
| 185 |
4/8✓ Branch 0 taken 132530 times.
✓ Branch 1 taken 944 times.
✓ Branch 2 taken 3974 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 142116682 times.
|
142254130 | switch (*data) { |
| 186 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 132530 times.
|
132530 | case '"': if (fputs("\\\"", file->file) < 0) OMC_ERROR_WRITE();break; |
| 187 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 944 times.
|
944 | case '\\': if (fputs("\\\\", file->file) < 0) OMC_ERROR_WRITE();break; |
| 188 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3974 times.
|
3974 | case '\n': if (fputs("\\n", file->file) < 0) OMC_ERROR_WRITE();break; |
| 189 | ✗ | case '\b': if (fputs("\\b", file->file) < 0) OMC_ERROR_WRITE();break; | |
| 190 | ✗ | case '\f': if (fputs("\\f", file->file) < 0) OMC_ERROR_WRITE();break; | |
| 191 | ✗ | case '\r': if (fputs("\\r", file->file) < 0) OMC_ERROR_WRITE();break; | |
| 192 | ✗ | case '\t': if (fputs("\\t", file->file) < 0) OMC_ERROR_WRITE();break; | |
| 193 | 142116682 | default: | |
| 194 |
2/2✓ Branch 0 taken 104 times.
✓ Branch 1 taken 142116578 times.
|
142116682 | if (*data < ' ') { /* Escape other control characters */ |
| 195 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 104 times.
|
104 | if (fprintf(file->file, "\\u%04x",*data) < 0) OMC_ERROR_WRITE(); |
| 196 | } else { | ||
| 197 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 142116578 times.
|
142116578 | if (putc(*data, file->file) < 0) OMC_ERROR_WRITE(); |
| 198 | } | ||
| 199 | } | ||
| 200 | 142254130 | data++; | |
| 201 | } | ||
| 202 | break; | ||
| 203 | case XML: | ||
| 204 |
2/2✓ Branch 0 taken 61902721 times.
✓ Branch 1 taken 2570240 times.
|
64472961 | while (*data) { |
| 205 |
5/6✓ Branch 0 taken 5572 times.
✓ Branch 1 taken 5302 times.
✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4647 times.
✓ Branch 5 taken 61887124 times.
|
61902721 | switch (*data) { |
| 206 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5572 times.
|
5572 | case '<': if (fputs("<", file->file) < 0) OMC_ERROR_WRITE();break; |
| 207 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5302 times.
|
5302 | case '>': if (fputs(">", file->file) < 0) OMC_ERROR_WRITE();break; |
| 208 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
|
76 | case '"': if (fputs(""", file->file) < 0) OMC_ERROR_WRITE();break; |
| 209 | ✗ | case '&': if (fputs("&", file->file) < 0) OMC_ERROR_WRITE();break; | |
| 210 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4647 times.
|
4647 | case '\'': if (fputs("'", file->file) < 0) OMC_ERROR_WRITE();break; |
| 211 | 61887124 | default: | |
| 212 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 61887124 times.
|
61887124 | if (putc(*data, file->file) < 0) OMC_ERROR_WRITE(); |
| 213 | } | ||
| 214 | 61902721 | data++; | |
| 215 | } | ||
| 216 | break; | ||
| 217 | ✗ | default: | |
| 218 | ✗ | ModelicaFormatError("File.writeEscape: No such escape enumeration: %d\n", escape); | |
| 219 | } | ||
| 220 | 9812286 | } | |
| 221 | |||
| 222 | ✗ | static inline int om_file_seek(__OMC_FILE *file, int offset, enum whence_t whence) | |
| 223 | { | ||
| 224 | ✗ | if (!file->file) { | |
| 225 | return 0; | ||
| 226 | } | ||
| 227 | ✗ | return 0 == fseek(file->file, offset, whence == OMC_SEEK_SET ? SEEK_SET : whence == OMC_SEEK_CURRENT ? SEEK_CUR : SEEK_END); | |
| 228 | } | ||
| 229 | |||
| 230 | static inline int om_file_tell(__OMC_FILE *file) | ||
| 231 | { | ||
| 232 |
1/2✓ Branch 0 taken 743914 times.
✗ Branch 1 not taken.
|
743914 | if (!file->file) { |
| 233 | return -1; | ||
| 234 | } | ||
| 235 | 743914 | return ftell(file->file); | |
| 236 | } | ||
| 237 | |||
| 238 | static inline void* om_file_get_filename(__OMC_FILE *file) | ||
| 239 | { | ||
| 240 | #if defined(__OMC_FILE_DEBUG) | ||
| 241 | fprintf(stderr,"File.getFilename: %s, %p %p\n", file->name, file->file, file); fflush(NULL); | ||
| 242 | #endif | ||
| 243 | ✗ | return mmc_mk_scon(file->name); | |
| 244 | } | ||
| 245 | |||
| 246 | static inline void* om_file_no_reference() | ||
| 247 | { | ||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | |||
| 251 | static inline void* om_file_get_reference(__OMC_FILE *file) | ||
| 252 | { | ||
| 253 | #if defined(__OMC_FILE_DEBUG) | ||
| 254 | fprintf(stderr,"File.getReference: %s, %p %p\n", file->name, file->file, file); fflush(NULL); | ||
| 255 | #endif | ||
| 256 | 31787 | file->cnt++; | |
| 257 | return file; | ||
| 258 | } | ||
| 259 | |||
| 260 | static inline void* om_file_release_reference(__OMC_FILE *file) | ||
| 261 | { | ||
| 262 | 31787 | file->cnt--; | |
| 263 | return file; | ||
| 264 | } | ||
| 265 | |||
| 266 | #endif /* __OMC_FILE_H */ | ||
| 267 |