18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#define _GNU_SOURCE 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <stdio.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include "dtc.h" 118c2ecf20Sopenharmony_ci#include "srcpos.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* A node in our list of directories to search for source/include files */ 148c2ecf20Sopenharmony_cistruct search_path { 158c2ecf20Sopenharmony_ci struct search_path *next; /* next node in list, NULL for end */ 168c2ecf20Sopenharmony_ci const char *dirname; /* name of directory to search */ 178c2ecf20Sopenharmony_ci}; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* This is the list of directories that we search for source files */ 208c2ecf20Sopenharmony_cistatic struct search_path *search_path_head, **search_path_tail; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* Detect infinite include recursion. */ 238c2ecf20Sopenharmony_ci#define MAX_SRCFILE_DEPTH (100) 248c2ecf20Sopenharmony_cistatic int srcfile_depth; /* = 0 */ 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistatic char *get_dirname(const char *path) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci const char *slash = strrchr(path, '/'); 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci if (slash) { 318c2ecf20Sopenharmony_ci int len = slash - path; 328c2ecf20Sopenharmony_ci char *dir = xmalloc(len + 1); 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci memcpy(dir, path, len); 358c2ecf20Sopenharmony_ci dir[len] = '\0'; 368c2ecf20Sopenharmony_ci return dir; 378c2ecf20Sopenharmony_ci } 388c2ecf20Sopenharmony_ci return NULL; 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ciFILE *depfile; /* = NULL */ 428c2ecf20Sopenharmony_cistruct srcfile_state *current_srcfile; /* = NULL */ 438c2ecf20Sopenharmony_cistatic char *initial_path; /* = NULL */ 448c2ecf20Sopenharmony_cistatic int initial_pathlen; /* = 0 */ 458c2ecf20Sopenharmony_cistatic bool initial_cpp = true; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic void set_initial_path(char *fname) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci int i, len = strlen(fname); 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci xasprintf(&initial_path, "%s", fname); 528c2ecf20Sopenharmony_ci initial_pathlen = 0; 538c2ecf20Sopenharmony_ci for (i = 0; i != len; i++) 548c2ecf20Sopenharmony_ci if (initial_path[i] == '/') 558c2ecf20Sopenharmony_ci initial_pathlen++; 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistatic char *shorten_to_initial_path(char *fname) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci char *p1, *p2, *prevslash1 = NULL; 618c2ecf20Sopenharmony_ci int slashes = 0; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci for (p1 = fname, p2 = initial_path; *p1 && *p2; p1++, p2++) { 648c2ecf20Sopenharmony_ci if (*p1 != *p2) 658c2ecf20Sopenharmony_ci break; 668c2ecf20Sopenharmony_ci if (*p1 == '/') { 678c2ecf20Sopenharmony_ci prevslash1 = p1; 688c2ecf20Sopenharmony_ci slashes++; 698c2ecf20Sopenharmony_ci } 708c2ecf20Sopenharmony_ci } 718c2ecf20Sopenharmony_ci p1 = prevslash1 + 1; 728c2ecf20Sopenharmony_ci if (prevslash1) { 738c2ecf20Sopenharmony_ci int diff = initial_pathlen - slashes, i, j; 748c2ecf20Sopenharmony_ci int restlen = strlen(fname) - (p1 - fname); 758c2ecf20Sopenharmony_ci char *res; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci res = xmalloc((3 * diff) + restlen + 1); 788c2ecf20Sopenharmony_ci for (i = 0, j = 0; i != diff; i++) { 798c2ecf20Sopenharmony_ci res[j++] = '.'; 808c2ecf20Sopenharmony_ci res[j++] = '.'; 818c2ecf20Sopenharmony_ci res[j++] = '/'; 828c2ecf20Sopenharmony_ci } 838c2ecf20Sopenharmony_ci strcpy(res + j, p1); 848c2ecf20Sopenharmony_ci return res; 858c2ecf20Sopenharmony_ci } 868c2ecf20Sopenharmony_ci return NULL; 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci/** 908c2ecf20Sopenharmony_ci * Try to open a file in a given directory. 918c2ecf20Sopenharmony_ci * 928c2ecf20Sopenharmony_ci * If the filename is an absolute path, then dirname is ignored. If it is a 938c2ecf20Sopenharmony_ci * relative path, then we look in that directory for the file. 948c2ecf20Sopenharmony_ci * 958c2ecf20Sopenharmony_ci * @param dirname Directory to look in, or NULL for none 968c2ecf20Sopenharmony_ci * @param fname Filename to look for 978c2ecf20Sopenharmony_ci * @param fp Set to NULL if file did not open 988c2ecf20Sopenharmony_ci * @return allocated filename on success (caller must free), NULL on failure 998c2ecf20Sopenharmony_ci */ 1008c2ecf20Sopenharmony_cistatic char *try_open(const char *dirname, const char *fname, FILE **fp) 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci char *fullname; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci if (!dirname || fname[0] == '/') 1058c2ecf20Sopenharmony_ci fullname = xstrdup(fname); 1068c2ecf20Sopenharmony_ci else 1078c2ecf20Sopenharmony_ci fullname = join_path(dirname, fname); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci *fp = fopen(fullname, "rb"); 1108c2ecf20Sopenharmony_ci if (!*fp) { 1118c2ecf20Sopenharmony_ci free(fullname); 1128c2ecf20Sopenharmony_ci fullname = NULL; 1138c2ecf20Sopenharmony_ci } 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci return fullname; 1168c2ecf20Sopenharmony_ci} 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci/** 1198c2ecf20Sopenharmony_ci * Open a file for read access 1208c2ecf20Sopenharmony_ci * 1218c2ecf20Sopenharmony_ci * If it is a relative filename, we search the full search path for it. 1228c2ecf20Sopenharmony_ci * 1238c2ecf20Sopenharmony_ci * @param fname Filename to open 1248c2ecf20Sopenharmony_ci * @param fp Returns pointer to opened FILE, or NULL on failure 1258c2ecf20Sopenharmony_ci * @return pointer to allocated filename, which caller must free 1268c2ecf20Sopenharmony_ci */ 1278c2ecf20Sopenharmony_cistatic char *fopen_any_on_path(const char *fname, FILE **fp) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci const char *cur_dir = NULL; 1308c2ecf20Sopenharmony_ci struct search_path *node; 1318c2ecf20Sopenharmony_ci char *fullname; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci /* Try current directory first */ 1348c2ecf20Sopenharmony_ci assert(fp); 1358c2ecf20Sopenharmony_ci if (current_srcfile) 1368c2ecf20Sopenharmony_ci cur_dir = current_srcfile->dir; 1378c2ecf20Sopenharmony_ci fullname = try_open(cur_dir, fname, fp); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci /* Failing that, try each search path in turn */ 1408c2ecf20Sopenharmony_ci for (node = search_path_head; !*fp && node; node = node->next) 1418c2ecf20Sopenharmony_ci fullname = try_open(node->dirname, fname, fp); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci return fullname; 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ciFILE *srcfile_relative_open(const char *fname, char **fullnamep) 1478c2ecf20Sopenharmony_ci{ 1488c2ecf20Sopenharmony_ci FILE *f; 1498c2ecf20Sopenharmony_ci char *fullname; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci if (streq(fname, "-")) { 1528c2ecf20Sopenharmony_ci f = stdin; 1538c2ecf20Sopenharmony_ci fullname = xstrdup("<stdin>"); 1548c2ecf20Sopenharmony_ci } else { 1558c2ecf20Sopenharmony_ci fullname = fopen_any_on_path(fname, &f); 1568c2ecf20Sopenharmony_ci if (!f) 1578c2ecf20Sopenharmony_ci die("Couldn't open \"%s\": %s\n", fname, 1588c2ecf20Sopenharmony_ci strerror(errno)); 1598c2ecf20Sopenharmony_ci } 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci if (depfile) 1628c2ecf20Sopenharmony_ci fprintf(depfile, " %s", fullname); 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci if (fullnamep) 1658c2ecf20Sopenharmony_ci *fullnamep = fullname; 1668c2ecf20Sopenharmony_ci else 1678c2ecf20Sopenharmony_ci free(fullname); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci return f; 1708c2ecf20Sopenharmony_ci} 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_civoid srcfile_push(const char *fname) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci struct srcfile_state *srcfile; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci if (srcfile_depth++ >= MAX_SRCFILE_DEPTH) 1778c2ecf20Sopenharmony_ci die("Includes nested too deeply"); 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci srcfile = xmalloc(sizeof(*srcfile)); 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci srcfile->f = srcfile_relative_open(fname, &srcfile->name); 1828c2ecf20Sopenharmony_ci srcfile->dir = get_dirname(srcfile->name); 1838c2ecf20Sopenharmony_ci srcfile->prev = current_srcfile; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci srcfile->lineno = 1; 1868c2ecf20Sopenharmony_ci srcfile->colno = 1; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci current_srcfile = srcfile; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci if (srcfile_depth == 1) 1918c2ecf20Sopenharmony_ci set_initial_path(srcfile->name); 1928c2ecf20Sopenharmony_ci} 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_cibool srcfile_pop(void) 1958c2ecf20Sopenharmony_ci{ 1968c2ecf20Sopenharmony_ci struct srcfile_state *srcfile = current_srcfile; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci assert(srcfile); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci current_srcfile = srcfile->prev; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci if (fclose(srcfile->f)) 2038c2ecf20Sopenharmony_ci die("Error closing \"%s\": %s\n", srcfile->name, 2048c2ecf20Sopenharmony_ci strerror(errno)); 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci /* FIXME: We allow the srcfile_state structure to leak, 2078c2ecf20Sopenharmony_ci * because it could still be referenced from a location 2088c2ecf20Sopenharmony_ci * variable being carried through the parser somewhere. To 2098c2ecf20Sopenharmony_ci * fix this we could either allocate all the files from a 2108c2ecf20Sopenharmony_ci * table, or use a pool allocator. */ 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci return current_srcfile ? true : false; 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_civoid srcfile_add_search_path(const char *dirname) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci struct search_path *node; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci /* Create the node */ 2208c2ecf20Sopenharmony_ci node = xmalloc(sizeof(*node)); 2218c2ecf20Sopenharmony_ci node->next = NULL; 2228c2ecf20Sopenharmony_ci node->dirname = xstrdup(dirname); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci /* Add to the end of our list */ 2258c2ecf20Sopenharmony_ci if (search_path_tail) 2268c2ecf20Sopenharmony_ci *search_path_tail = node; 2278c2ecf20Sopenharmony_ci else 2288c2ecf20Sopenharmony_ci search_path_head = node; 2298c2ecf20Sopenharmony_ci search_path_tail = &node->next; 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_civoid srcpos_update(struct srcpos *pos, const char *text, int len) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci int i; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci pos->file = current_srcfile; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci pos->first_line = current_srcfile->lineno; 2398c2ecf20Sopenharmony_ci pos->first_column = current_srcfile->colno; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) 2428c2ecf20Sopenharmony_ci if (text[i] == '\n') { 2438c2ecf20Sopenharmony_ci current_srcfile->lineno++; 2448c2ecf20Sopenharmony_ci current_srcfile->colno = 1; 2458c2ecf20Sopenharmony_ci } else { 2468c2ecf20Sopenharmony_ci current_srcfile->colno++; 2478c2ecf20Sopenharmony_ci } 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci pos->last_line = current_srcfile->lineno; 2508c2ecf20Sopenharmony_ci pos->last_column = current_srcfile->colno; 2518c2ecf20Sopenharmony_ci} 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_cistruct srcpos * 2548c2ecf20Sopenharmony_cisrcpos_copy(struct srcpos *pos) 2558c2ecf20Sopenharmony_ci{ 2568c2ecf20Sopenharmony_ci struct srcpos *pos_new; 2578c2ecf20Sopenharmony_ci struct srcfile_state *srcfile_state; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci if (!pos) 2608c2ecf20Sopenharmony_ci return NULL; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci pos_new = xmalloc(sizeof(struct srcpos)); 2638c2ecf20Sopenharmony_ci assert(pos->next == NULL); 2648c2ecf20Sopenharmony_ci memcpy(pos_new, pos, sizeof(struct srcpos)); 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci /* allocate without free */ 2678c2ecf20Sopenharmony_ci srcfile_state = xmalloc(sizeof(struct srcfile_state)); 2688c2ecf20Sopenharmony_ci memcpy(srcfile_state, pos->file, sizeof(struct srcfile_state)); 2698c2ecf20Sopenharmony_ci pos_new->file = srcfile_state; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci return pos_new; 2728c2ecf20Sopenharmony_ci} 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_cistruct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail) 2758c2ecf20Sopenharmony_ci{ 2768c2ecf20Sopenharmony_ci struct srcpos *p; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci if (!pos) 2798c2ecf20Sopenharmony_ci return newtail; 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci for (p = pos; p->next != NULL; p = p->next); 2828c2ecf20Sopenharmony_ci p->next = newtail; 2838c2ecf20Sopenharmony_ci return pos; 2848c2ecf20Sopenharmony_ci} 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_cichar * 2878c2ecf20Sopenharmony_cisrcpos_string(struct srcpos *pos) 2888c2ecf20Sopenharmony_ci{ 2898c2ecf20Sopenharmony_ci const char *fname = "<no-file>"; 2908c2ecf20Sopenharmony_ci char *pos_str; 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci if (pos->file && pos->file->name) 2938c2ecf20Sopenharmony_ci fname = pos->file->name; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci if (pos->first_line != pos->last_line) 2978c2ecf20Sopenharmony_ci xasprintf(&pos_str, "%s:%d.%d-%d.%d", fname, 2988c2ecf20Sopenharmony_ci pos->first_line, pos->first_column, 2998c2ecf20Sopenharmony_ci pos->last_line, pos->last_column); 3008c2ecf20Sopenharmony_ci else if (pos->first_column != pos->last_column) 3018c2ecf20Sopenharmony_ci xasprintf(&pos_str, "%s:%d.%d-%d", fname, 3028c2ecf20Sopenharmony_ci pos->first_line, pos->first_column, 3038c2ecf20Sopenharmony_ci pos->last_column); 3048c2ecf20Sopenharmony_ci else 3058c2ecf20Sopenharmony_ci xasprintf(&pos_str, "%s:%d.%d", fname, 3068c2ecf20Sopenharmony_ci pos->first_line, pos->first_column); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci return pos_str; 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_cistatic char * 3128c2ecf20Sopenharmony_cisrcpos_string_comment(struct srcpos *pos, bool first_line, int level) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci char *pos_str, *fname, *first, *rest; 3158c2ecf20Sopenharmony_ci bool fresh_fname = false; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci if (!pos) { 3188c2ecf20Sopenharmony_ci if (level > 1) { 3198c2ecf20Sopenharmony_ci xasprintf(&pos_str, "<no-file>:<no-line>"); 3208c2ecf20Sopenharmony_ci return pos_str; 3218c2ecf20Sopenharmony_ci } else { 3228c2ecf20Sopenharmony_ci return NULL; 3238c2ecf20Sopenharmony_ci } 3248c2ecf20Sopenharmony_ci } 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci if (!pos->file) 3278c2ecf20Sopenharmony_ci fname = "<no-file>"; 3288c2ecf20Sopenharmony_ci else if (!pos->file->name) 3298c2ecf20Sopenharmony_ci fname = "<no-filename>"; 3308c2ecf20Sopenharmony_ci else if (level > 1) 3318c2ecf20Sopenharmony_ci fname = pos->file->name; 3328c2ecf20Sopenharmony_ci else { 3338c2ecf20Sopenharmony_ci fname = shorten_to_initial_path(pos->file->name); 3348c2ecf20Sopenharmony_ci if (fname) 3358c2ecf20Sopenharmony_ci fresh_fname = true; 3368c2ecf20Sopenharmony_ci else 3378c2ecf20Sopenharmony_ci fname = pos->file->name; 3388c2ecf20Sopenharmony_ci } 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci if (level > 1) 3418c2ecf20Sopenharmony_ci xasprintf(&first, "%s:%d:%d-%d:%d", fname, 3428c2ecf20Sopenharmony_ci pos->first_line, pos->first_column, 3438c2ecf20Sopenharmony_ci pos->last_line, pos->last_column); 3448c2ecf20Sopenharmony_ci else 3458c2ecf20Sopenharmony_ci xasprintf(&first, "%s:%d", fname, 3468c2ecf20Sopenharmony_ci first_line ? pos->first_line : pos->last_line); 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci if (fresh_fname) 3498c2ecf20Sopenharmony_ci free(fname); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci if (pos->next != NULL) { 3528c2ecf20Sopenharmony_ci rest = srcpos_string_comment(pos->next, first_line, level); 3538c2ecf20Sopenharmony_ci xasprintf(&pos_str, "%s, %s", first, rest); 3548c2ecf20Sopenharmony_ci free(first); 3558c2ecf20Sopenharmony_ci free(rest); 3568c2ecf20Sopenharmony_ci } else { 3578c2ecf20Sopenharmony_ci pos_str = first; 3588c2ecf20Sopenharmony_ci } 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci return pos_str; 3618c2ecf20Sopenharmony_ci} 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_cichar *srcpos_string_first(struct srcpos *pos, int level) 3648c2ecf20Sopenharmony_ci{ 3658c2ecf20Sopenharmony_ci return srcpos_string_comment(pos, true, level); 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_cichar *srcpos_string_last(struct srcpos *pos, int level) 3698c2ecf20Sopenharmony_ci{ 3708c2ecf20Sopenharmony_ci return srcpos_string_comment(pos, false, level); 3718c2ecf20Sopenharmony_ci} 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_civoid srcpos_verror(struct srcpos *pos, const char *prefix, 3748c2ecf20Sopenharmony_ci const char *fmt, va_list va) 3758c2ecf20Sopenharmony_ci{ 3768c2ecf20Sopenharmony_ci char *srcstr; 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci srcstr = srcpos_string(pos); 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci fprintf(stderr, "%s: %s ", prefix, srcstr); 3818c2ecf20Sopenharmony_ci vfprintf(stderr, fmt, va); 3828c2ecf20Sopenharmony_ci fprintf(stderr, "\n"); 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci free(srcstr); 3858c2ecf20Sopenharmony_ci} 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_civoid srcpos_error(struct srcpos *pos, const char *prefix, 3888c2ecf20Sopenharmony_ci const char *fmt, ...) 3898c2ecf20Sopenharmony_ci{ 3908c2ecf20Sopenharmony_ci va_list va; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci va_start(va, fmt); 3938c2ecf20Sopenharmony_ci srcpos_verror(pos, prefix, fmt, va); 3948c2ecf20Sopenharmony_ci va_end(va); 3958c2ecf20Sopenharmony_ci} 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_civoid srcpos_set_line(char *f, int l) 3988c2ecf20Sopenharmony_ci{ 3998c2ecf20Sopenharmony_ci current_srcfile->name = f; 4008c2ecf20Sopenharmony_ci current_srcfile->lineno = l; 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci if (initial_cpp) { 4038c2ecf20Sopenharmony_ci initial_cpp = false; 4048c2ecf20Sopenharmony_ci set_initial_path(f); 4058c2ecf20Sopenharmony_ci } 4068c2ecf20Sopenharmony_ci} 407