145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * File helper functions. 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright (C) 2001-2007 Peter Johnson 545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without 745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions 845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met: 945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1. Redistributions of source code must retain the above copyright 1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * notice, this list of conditions and the following disclaimer. 1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * notice, this list of conditions and the following disclaimer in the 1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * documentation and/or other materials provided with the distribution. 1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE. 2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <util.h> 2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 29d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org/* Need either unistd.h or direct.h to prototype getcwd() and mkdir() */ 30d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org#ifdef HAVE_UNISTD_H 3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <unistd.h> 32d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org#endif 33d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org 34d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org#ifdef HAVE_DIRECT_H 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <direct.h> 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 38a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#ifdef _WIN32 39a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#include <io.h> 40a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#endif 41a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 42a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#ifdef HAVE_SYS_STAT_H 43a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#include <sys/stat.h> 44a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#endif 45a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <ctype.h> 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <errno.h> 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "errwarn.h" 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "file.h" 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define BSIZE 8192 /* Fill block size */ 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_scanner_initialize(yasm_scanner *s) 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->bot = NULL; 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->tok = NULL; 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->ptr = NULL; 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->cur = NULL; 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->lim = NULL; 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->top = NULL; 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->eof = NULL; 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_scanner_delete(yasm_scanner *s) 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (s->bot) { 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(s->bot); 7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->bot = NULL; 7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint 7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_fill_helper(yasm_scanner *s, unsigned char **cursor, 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t (*input_func) (void *d, unsigned char *buf, 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t max), 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void *input_func_data) 8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t cnt; 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int first = 0; 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (s->eof) 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cnt = s->tok - s->bot; 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (cnt > 0) { 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memmove(s->bot, s->tok, (size_t)(s->lim - s->tok)); 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->tok = s->bot; 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->ptr -= cnt; 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *cursor -= cnt; 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->lim -= cnt; 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!s->bot) 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org first = 1; 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((s->top - s->lim) < BSIZE) { 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned char *buf = yasm_xmalloc((size_t)(s->lim - s->bot) + BSIZE); 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memcpy(buf, s->tok, (size_t)(s->lim - s->tok)); 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->tok = buf; 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->ptr = &buf[s->ptr - s->bot]; 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *cursor = &buf[*cursor - s->bot]; 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->lim = &buf[s->lim - s->bot]; 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->top = &s->lim[BSIZE]; 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (s->bot) 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(s->bot); 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->bot = buf; 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((cnt = input_func(input_func_data, s->lim, BSIZE)) == 0) { 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->eof = &s->lim[cnt]; 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *s->eof++ = '\n'; 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s->lim += cnt; 11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return first; 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_unescape_cstring(unsigned char *str, size_t *len) 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned char *s = str; 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned char *o = str; 12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned char t[4]; 12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while ((size_t)(s-str)<*len) { 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*s == '\\' && (size_t)(&s[1]-str)<*len) { 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s++; 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org switch (*s) { 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'b': *o = '\b'; s++; break; 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'f': *o = '\f'; s++; break; 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'n': *o = '\n'; s++; break; 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'r': *o = '\r'; s++; break; 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 't': *o = '\t'; s++; break; 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org case 'x': 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* hex escape; grab last two digits */ 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s++; 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while ((size_t)(&s[2]-str)<*len && isxdigit(s[0]) 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && isxdigit(s[1]) && isxdigit(s[2])) 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s++; 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((size_t)(s-str)<*len && isxdigit(*s)) { 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t[0] = *s++; 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t[1] = '\0'; 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t[2] = '\0'; 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((size_t)(s-str)<*len && isxdigit(*s)) 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org t[1] = *s++; 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *o = (unsigned char)strtoul((char *)t, NULL, 16); 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *o = '\0'; 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org default: 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (isdigit(*s)) { 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int warn = 0; 15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* octal escape */ 15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*s > '7') 15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org warn = 1; 15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *o = *s++ - '0'; 15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((size_t)(s-str)<*len && isdigit(*s)) { 15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*s > '7') 15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org warn = 1; 16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *o <<= 3; 16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *o += *s++ - '0'; 16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((size_t)(s-str)<*len && isdigit(*s)) { 16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*s > '7') 16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org warn = 1; 16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *o <<= 3; 16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *o += *s++ - '0'; 16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (warn) 17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_warn_set(YASM_WARN_GENERAL, 17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("octal value out of range")); 17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *o = *s++; 17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org o++; 17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *o++ = *s++; 17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *len = o-str; 18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsize_t 18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm__splitpath_unix(const char *path, /*@out@*/ const char **tail) 18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *s; 18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = strrchr(path, '/'); 18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!s) { 18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* No head */ 19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = path; 19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = s+1; 19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Strip trailing ./ on path */ 19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while ((s-1)>=path && *(s-1) == '.' && *s == '/' 19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && !((s-2)>=path && *(s-2) == '.')) 19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s -= 2; 19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Strip trailing slashes on path (except leading) */ 19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (s>path && *s == '/') 20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s--; 20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Return length of head */ 20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return s-path+1; 20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsize_t 20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm__splitpath_win(const char *path, /*@out@*/ const char **tail) 20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *basepath = path; 20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *s; 21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* split off drive letter first, if any */ 21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (isalpha(path[0]) && path[1] == ':') 21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org basepath += 2; 21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = basepath; 21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*s != '\0') 21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s++; 21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (s >= basepath && *s != '\\' && *s != '/') 21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s--; 22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (s < basepath) { 22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = basepath; 22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (path == basepath) 22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; /* No head */ 22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 2; /* Drive letter is head */ 22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *tail = s+1; 22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Strip trailing .\ or ./ on path */ 22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while ((s-1)>=basepath && *(s-1) == '.' && (*s == '/' || *s == '\\') 23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && !((s-2)>=basepath && *(s-2) == '.')) 23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s -= 2; 23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Strip trailing slashes on path (except leading) */ 23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (s>basepath && (*s == '/' || *s == '\\')) 23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s--; 23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Return length of head */ 23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return s-path+1; 23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgchar * 24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm__getcwd(void) 24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *buf; 24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t size; 24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size = 1024; 24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org buf = yasm_xmalloc(size); 247d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org 248d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org if (getenv("YASM_TEST_SUITE")) { 249d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org strcpy(buf, "./"); 250d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org return buf; 251d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org } 252d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org 253a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org while (getcwd(buf, size-1) == NULL) { 25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (errno != ERANGE) { 25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm__fatal(N_("could not determine current working directory")); 25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(buf); 25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size *= 2; 26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org buf = yasm_xrealloc(buf, size); 26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 262a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 263a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org /* append a '/' if not already present */ 264a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org size = strlen(buf); 265a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (buf[size-1] != '\\' && buf[size-1] != '/') { 266a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org buf[size] = '/'; 267a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org buf[size+1] = '\0'; 268a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return buf; 27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgchar * 27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm__abspath(const char *path) 27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *curdir, *abspath; 27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org curdir = yasm__getcwd(); 27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org abspath = yasm__combpath(curdir, path); 27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(curdir); 28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return abspath; 28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgchar * 28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm__combpath_unix(const char *from, const char *to) 28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *tail; 28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t pathlen, i, j; 28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *out; 29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (to[0] == '/') { 29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* absolute "to" */ 29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out = yasm_xmalloc(strlen(to)+1); 29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Combine any double slashes when copying */ 29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (j=0; *to; to++) { 29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*to == '/' && *(to+1) == '/') 29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = *to; 29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = '\0'; 30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return out; 30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Get path component; note this strips trailing slash */ 30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pathlen = yasm__splitpath_unix(from, &tail); 30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out = yasm_xmalloc(pathlen+strlen(to)+2); /* worst case maximum len */ 30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Combine any double slashes when copying */ 31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0, j=0; i<pathlen; i++) { 31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i<pathlen-1 && from[i] == '/' && from[i+1] == '/') 31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = from[i]; 31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pathlen = j; 31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Add trailing slash back in */ 31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (pathlen > 0 && out[pathlen-1] != '/') 31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[pathlen++] = '/'; 32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Now scan from left to right through "to", stripping off "." and ".."; 32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * if we see "..", back up one directory in out unless last directory in 32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * out is also "..". 32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Note this does NOT back through ..'s in the "from" path; this is just 32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * as well as that could skip symlinks (e.g. "foo/bar/.." might not be 32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the same as "foo"). 32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (;;) { 33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (to[0] == '.' && to[1] == '/') { 33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org to += 2; /* current directory */ 33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*to == '/') 33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org to++; /* strip off any additional slashes */ 33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (pathlen == 0) 33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; /* no more "from" path left, we're done */ 33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (to[0] == '.' && to[1] == '.' && to[2] == '/') { 33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (pathlen >= 3 && out[pathlen-1] == '/' && out[pathlen-2] == '.' 33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && out[pathlen-3] == '.') { 33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* can't ".." against a "..", so we're done. */ 34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org to += 3; /* throw away "../" */ 34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*to == '/') 34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org to++; /* strip off any additional slashes */ 34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* and back out last directory in "out" if not already at root */ 34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (pathlen > 1) { 34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pathlen--; /* strip off trailing '/' */ 35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (pathlen > 0 && out[pathlen-1] != '/') 35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pathlen--; 35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Copy "to" to tail of output, and we're done */ 35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Combine any double slashes when copying */ 35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (j=pathlen; *to; to++) { 36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*to == '/' && *(to+1) == '/') 36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = *to; 36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = '\0'; 36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return out; 36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgchar * 37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm__combpath_win(const char *from, const char *to) 37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const char *tail; 37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t pathlen, i, j; 37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *out; 37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((isalpha(to[0]) && to[1] == ':') || (to[0] == '/' || to[0] == '\\')) { 37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* absolute or drive letter "to" */ 37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out = yasm_xmalloc(strlen(to)+1); 37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Combine any double slashes when copying */ 38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (j=0; *to; to++) { 38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((*to == '/' || *to == '\\') 38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && (*(to+1) == '/' || *(to+1) == '\\')) 38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*to == '/') 38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = '\\'; 38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = *to; 38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = '\0'; 39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return out; 39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Get path component; note this strips trailing slash */ 39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pathlen = yasm__splitpath_win(from, &tail); 39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out = yasm_xmalloc(pathlen+strlen(to)+2); /* worst case maximum len */ 39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Combine any double slashes when copying */ 39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (i=0, j=0; i<pathlen; i++) { 40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (i<pathlen-1 && (from[i] == '/' || from[i] == '\\') 40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && (from[i+1] == '/' || from[i+1] == '\\')) 40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (from[i] == '/') 40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = '\\'; 40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = from[i]; 40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pathlen = j; 40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Add trailing slash back in, unless it's only a raw drive letter */ 41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (pathlen > 0 && out[pathlen-1] != '\\' 41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && !(pathlen == 2 && isalpha(out[0]) && out[1] == ':')) 41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[pathlen++] = '\\'; 41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Now scan from left to right through "to", stripping off "." and ".."; 41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * if we see "..", back up one directory in out unless last directory in 41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * out is also "..". 41845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 41945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Note this does NOT back through ..'s in the "from" path; this is just 42045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * as well as that could skip symlinks (e.g. "foo/bar/.." might not be 42145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the same as "foo"). 42245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 42345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (;;) { 42445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (to[0] == '.' && (to[1] == '/' || to[1] == '\\')) { 42545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org to += 2; /* current directory */ 42645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*to == '/' || *to == '\\') 42745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org to++; /* strip off any additional slashes */ 42845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else if (pathlen == 0 42945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org || (pathlen == 2 && isalpha(out[0]) && out[1] == ':')) 43045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; /* no more "from" path left, we're done */ 43145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else if (to[0] == '.' && to[1] == '.' 43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && (to[2] == '/' || to[2] == '\\')) { 43345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (pathlen >= 3 && out[pathlen-1] == '\\' 43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org && out[pathlen-2] == '.' && out[pathlen-3] == '.') { 43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* can't ".." against a "..", so we're done. */ 43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org to += 3; /* throw away "../" (or "..\") */ 44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (*to == '/' || *to == '\\') 44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org to++; /* strip off any additional slashes */ 44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* and back out last directory in "out" if not already at root */ 44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (pathlen > 1) { 44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pathlen--; /* strip off trailing '/' */ 44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (pathlen > 0 && out[pathlen-1] != '\\') 44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pathlen--; 44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } else 45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break; 45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Copy "to" to tail of output, and we're done */ 45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Combine any double slashes when copying */ 45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for (j=pathlen; *to; to++) { 45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if ((*to == '/' || *to == '\\') && (*(to+1) == '/' || *(to+1) == '\\')) 45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org continue; 45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (*to == '/') 45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = '\\'; 46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = *to; 46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org out[j++] = '\0'; 46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return out; 46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 468a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgsize_t 469a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgyasm__createpath_common(const char *path, int win) 470a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org{ 471a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org const char *pp = path, *pe; 472a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org char *ts, *tp; 473a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org size_t len, lth; 474a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 475a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org lth = len = strlen(path); 476a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org ts = tp = (char *) malloc(len + 1); 477a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org pe = pp + len; 478a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org while (pe > pp) { 479a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if ((win && *pe == '\\') || *pe == '/') 480a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 481a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org --pe; 482a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org --lth; 483a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 484a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 485a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org while (pp <= pe) { 486a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (pp == pe || (win && *pp == '\\') || *pp == '/') { 487a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#ifdef _WIN32 488a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org struct _finddata_t fi; 489a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org intptr_t h; 490a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#elif defined(HAVE_SYS_STAT_H) 491a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org struct stat fi; 492a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#endif 493a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org *tp = '\0'; 494a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 495a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#ifdef _WIN32 496a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org h = _findfirst(ts, &fi); 497a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (h != -1) { 498a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (fi.attrib != _A_SUBDIR) { 499a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org _findclose(h); 500a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 501a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 502a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } else if (errno == ENOENT) { 503a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (_mkdir(ts) == -1) { 504a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org _findclose(h); 505a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org lth = -1; 506a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 507a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 508a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 509a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org _findclose(h); 510a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#elif defined(HAVE_SYS_STAT_H) 511a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (stat(ts, &fi) != -1) { 512a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (!S_ISDIR(fi.st_mode)) 513a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 514a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } else if (errno == ENOENT) { 515a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org if (mkdir(ts, 0755) == -1) { 516a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org lth = 0; 517a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 518a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 519a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 520a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#else 521a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org break; 522a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org#endif 523a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 524a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org *tp++ = *pp++; 525a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org } 526a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org free(ts); 527a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org return lth; 528a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org} 529a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 53045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct incpath { 53145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_ENTRY(incpath) link; 53245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@owned@*/ char *path; 53345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} incpath; 53445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 535a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgSTAILQ_HEAD(incpath_head, incpath) incpaths = STAILQ_HEAD_INITIALIZER(incpaths); 53645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 53745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgFILE * 53845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_fopen_include(const char *iname, const char *from, const char *mode, 53945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char **oname) 54045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 54145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org FILE *f; 54245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org char *combine; 54345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org incpath *np; 54445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 54545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Try directly relative to from first, then each of the include paths */ 54645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (from) { 54745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org combine = yasm__combpath(from, iname); 54845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org f = fopen(combine, mode); 54945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (f) { 55045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (oname) 55145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *oname = combine; 55245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 55345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(combine); 55445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return f; 55545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 55645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(combine); 55745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 55845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 55945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_FOREACH(np, &incpaths, link) { 56045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org combine = yasm__combpath(np->path, iname); 56145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org f = fopen(combine, mode); 56245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (f) { 56345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (oname) 56445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *oname = combine; 56545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 56645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(combine); 56745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return f; 56845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 56945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(combine); 57045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 57145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 57245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (oname) 57345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *oname = NULL; 57445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 57545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 57645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 57745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 57845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_delete_include_paths(void) 57945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 58045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org incpath *n1, *n2; 58145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 58245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org n1 = STAILQ_FIRST(&incpaths); 58345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org while (n1) { 58445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org n2 = STAILQ_NEXT(n1, link); 58545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(n1->path); 58645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(n1); 58745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org n1 = n2; 58845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 58945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INIT(&incpaths); 59045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 59145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 59245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgconst char * 59345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_get_include_dir(void **iter) 59445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 59545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org incpath *p = (incpath *)*iter; 59645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 59745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (!p) 59845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = STAILQ_FIRST(&incpaths); 59945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 60045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org p = STAILQ_NEXT(p, link); 60145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 60245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *iter = p; 60345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (p) 60445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return p->path; 60545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else 60645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 60745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 60845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 60945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 61045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_add_include_path(const char *path) 61145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 61245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org incpath *np = yasm_xmalloc(sizeof(incpath)); 61345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t len = strlen(path); 61445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 61545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org np->path = yasm_xmalloc(len+2); 61645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org memcpy(np->path, path, len+1); 61745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* Add trailing slash if it is missing */ 61845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (path[len-1] != '\\' && path[len-1] != '/') { 61945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org np->path[len] = '/'; 62045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org np->path[len+1] = '\0'; 62145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 62245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 62345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org STAILQ_INSERT_TAIL(&incpaths, np, link); 62445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 62545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 62645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsize_t 62745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_fwrite_16_l(unsigned short val, FILE *f) 62845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 62945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc(val & 0xFF, f) == EOF) 63045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 63145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc((val >> 8) & 0xFF, f) == EOF) 63245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 63345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 63445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 63545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 63645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsize_t 63745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_fwrite_32_l(unsigned long val, FILE *f) 63845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 63945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc((int)(val & 0xFF), f) == EOF) 64045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 64145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc((int)((val >> 8) & 0xFF), f) == EOF) 64245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 64345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc((int)((val >> 16) & 0xFF), f) == EOF) 64445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 64545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc((int)((val >> 24) & 0xFF), f) == EOF) 64645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 64745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 64845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 64945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 65045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsize_t 65145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_fwrite_16_b(unsigned short val, FILE *f) 65245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 65345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc((val >> 8) & 0xFF, f) == EOF) 65445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 65545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc(val & 0xFF, f) == EOF) 65645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 65745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 65845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 65945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 66045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgsize_t 66145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_fwrite_32_b(unsigned long val, FILE *f) 66245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 66345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc((int)((val >> 24) & 0xFF), f) == EOF) 66445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 66545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc((int)((val >> 16) & 0xFF), f) == EOF) 66645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 66745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc((int)((val >> 8) & 0xFF), f) == EOF) 66845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 66945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (fputc((int)(val & 0xFF), f) == EOF) 67045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 67145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 67245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 673