1 /* 2 * renderer-msvc.c 3 * MSVC library syntax renderer 4 * 5 * SPDX-License-Identifier: pkgconf 6 * 7 * Copyright (c) 2017 pkgconf authors (see AUTHORS). 8 * 9 * Permission to use, copy, modify, and/or distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * This software is provided 'as is' and without any warranty, express or 14 * implied. In no event shall the authors be liable for any damages arising 15 * from the use of this software. 16 */ 17 18 #include <string.h> 19 #include <stdlib.h> 20 21 #include <libpkgconf/libpkgconf.h> 22 #include "renderer-msvc.h" 23 24 static inline bool 25 should_quote(const pkgconf_buffer_t *buf) 26 { 27 const char *src; 28 29 for (src = buf->base; *src && src < buf->end; src++) 30 { 31 if (((*src < ' ') || 32 (*src >= (' ') && *src < '$') || 33 (*src > '$' && *src < '(') || 34 (*src > ')' && *src < '+') || 35 (*src > ':' && *src < '=') || 36 (*src > '=' && *src < '@') || 37 (*src > 'Z' && *src < '^') || 38 (*src == '`') || 39 (*src > 'z' && *src < '~') || 40 (*src > '~'))) 41 return true; 42 } 43 44 return false; 45 } 46 47 static inline bool 48 allowed_fragment(const pkgconf_fragment_t *frag) 49 { 50 return !(!frag->type || frag->data == NULL || strchr("DILl", frag->type) == NULL); 51 } 52 53 static void 54 msvc_renderer_render(const pkgconf_fragment_render_ctx_t *ctx, const pkgconf_fragment_t *frag, pkgconf_buffer_t *buf) 55 { 56 pkgconf_buffer_t tmpbuf = PKGCONF_BUFFER_INITIALIZER; 57 bool escape = ctx->escape; 58 59 if (!allowed_fragment(frag)) 60 return; 61 62 switch(frag->type) { 63 case 'D': 64 case 'I': 65 pkgconf_buffer_append_fmt(buf, "/%c", frag->type); 66 break; 67 case 'L': 68 pkgconf_buffer_append(buf, "/libpath:"); 69 break; 70 } 71 72 pkgconf_buffer_append(&tmpbuf, frag->data); 73 74 if (frag->type == 'l') 75 pkgconf_buffer_append(&tmpbuf, ".lib"); 76 77 escape = should_quote(&tmpbuf); 78 79 if (escape) 80 pkgconf_buffer_push_byte(buf, '"'); 81 82 pkgconf_buffer_append(buf, pkgconf_buffer_str_or_empty(&tmpbuf)); 83 84 if (escape) 85 pkgconf_buffer_push_byte(buf, '"'); 86 87 pkgconf_buffer_finalize(&tmpbuf); 88 } 89 90 static pkgconf_fragment_render_ops_t msvc_renderer_ops = { 91 .render = msvc_renderer_render 92 }; 93 94 pkgconf_fragment_render_ops_t * 95 msvc_renderer_get(void) 96 { 97 return &msvc_renderer_ops; 98 } 99