Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-src by
Diff: cpp/stdio.cpp
- Revision:
- 2:143cac498751
- Parent:
- 1:62685faffa05
- Child:
- 5:ab1c572cb536
diff -r 62685faffa05 -r 143cac498751 cpp/stdio.cpp --- a/cpp/stdio.cpp Thu Nov 29 15:41:14 2012 +0000 +++ b/cpp/stdio.cpp Mon Feb 18 11:44:18 2013 +0000 @@ -1,31 +1,26 @@ /* mbed Microcontroller Library - * Copyright (c) 2006-2012 ARM Limited + * Copyright (c) 2006-2013 ARM Limited * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Licensed 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 * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. + * http://www.apache.org/licenses/LICENSE-2.0 * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * 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 "platform.h" #include "FileHandle.h" #include "FileSystemLike.h" +#include "FilePath.h" #include "serial_api.h" #include <errno.h> -#ifdef __ARMCC_VERSION +#if defined(__ARMCC_VERSION) # include <rt_sys.h> # define PREFIX(x) _sys##x # define OPEN_MAX _SYS_OPEN @@ -33,6 +28,15 @@ # pragma import(__use_full_stdio) # endif +#elif defined(__ICCARM__) +# include <yfuns.h> +# define PREFIX(x) _##x +# define OPEN_MAX 16 + +# define STDIN_FILENO 0 +# define STDOUT_FILENO 1 +# define STDERR_FILENO 2 + #else # include <sys/stat.h> # include <sys/unistd.h> @@ -76,30 +80,38 @@ #endif } +static inline int openmode_to_posix(int openmode) { + int posix = openmode; #ifdef __ARMCC_VERSION -static int rvct_openmode_to_posix(int openmode) { - /* RVCT openmode -> POSIX flags */ - int tmpmode = openmode; - if (tmpmode & OPEN_PLUS) { - openmode = O_RDWR; - } else if(tmpmode & OPEN_W) { - openmode = O_WRONLY; - } else if(tmpmode & OPEN_A) { - openmode = O_WRONLY|O_APPEND; + if (openmode & OPEN_PLUS) { + posix = O_RDWR; + } else if(openmode & OPEN_W) { + posix = O_WRONLY; + } else if(openmode & OPEN_A) { + posix = O_WRONLY|O_APPEND; } else { - openmode = O_RDONLY; + posix = O_RDONLY; } /* a, w, a+, w+ all create if file does not already exist */ - if (tmpmode & (OPEN_A|OPEN_W)) { - openmode |= O_CREAT; + if (openmode & (OPEN_A|OPEN_W)) { + posix |= O_CREAT; } /* w and w+ truncate */ - if (tmpmode & OPEN_W) { - openmode |= O_TRUNC; + if (openmode & OPEN_W) { + posix |= O_TRUNC; } - return openmode; +#elif defined(__ICCARM__) + switch (openmode & _LLIO_RDWRMASK) { + case _LLIO_RDONLY: posix = O_RDONLY; break; + case _LLIO_WRONLY: posix = O_WRONLY; break; + case _LLIO_RDWR : posix = O_RDWR ; break; + } + if (openmode & _LLIO_CREAT ) posix |= O_CREAT; + if (openmode & _LLIO_APPEND) posix |= O_APPEND; + if (openmode & _LLIO_TRUNC ) posix |= O_TRUNC; +#endif + return posix; } -#endif extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) { /* Use the posix convention that stdin,out,err are filehandles 0,1,2. @@ -114,7 +126,7 @@ init_serial(); return 2; } - + // find the first empty slot in filehandles unsigned int fh_i; for (fh_i = 0; fh_i < sizeof(filehandles)/sizeof(*filehandles); fh_i++) { @@ -123,44 +135,50 @@ if (fh_i >= sizeof(filehandles)/sizeof(*filehandles)) { return -1; } - + FileHandle *res; - + /* FILENAME: ":0x12345678" describes a FileLike* */ if (name[0] == ':') { void *p; sscanf(name, ":%p", &p); res = (FileHandle*)p; - + /* FILENAME: "/file_system/file_name" */ } else { FilePath path(name); - - FileSystemLike *fs = path.fileSystem(); - if (fs == NULL) return -1; - -#ifdef __ARMCC_VERSION - openmode = rvct_openmode_to_posix(openmode); -#endif - res = fs->open(path.fileName(), openmode); /* NULL if fails */ + + if (path.isFile()) { + res = path.file(); + } else { + FileSystemLike *fs = path.fileSystem(); + if (fs == NULL) return -1; + int posix_mode = openmode_to_posix(openmode); + res = fs->open(path.fileName(), posix_mode); /* NULL if fails */ + } } - + if (res == NULL) return -1; filehandles[fh_i] = res; + return fh_i + 3; // +3 as filehandles 0-2 are stdin/out/err } extern "C" int PREFIX(_close)(FILEHANDLE fh) { if (fh < 3) return 0; - + FileHandle* fhc = filehandles[fh-3]; filehandles[fh-3] = NULL; if (fhc == NULL) return -1; - + return fhc->close(); } -extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char* buffer, unsigned int length, int mode) { +#if defined(__ICCARM__) +extern "C" size_t __write (int fh, const unsigned char *buffer, size_t length) { +#else +extern "C" int PREFIX(_write)(FILEHANDLE fh, const unsigned char *buffer, unsigned int length, int mode) { +#endif int n; // n is the number of bytes written if (fh < 3) { #if DEVICE_SERIAL @@ -173,17 +191,21 @@ } else { FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + n = fhc->write(buffer, length); } #ifdef __ARMCC_VERSION return length-n; #else return n; -#endif +#endif } -extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char* buffer, unsigned int length, int mode) { +#if defined(__ICCARM__) +extern "C" size_t __read (int fh, unsigned char *buffer, size_t length) { +#else +extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int length, int mode) { +#endif int n; // n is the number of bytes read if (fh < 3) { // only read a character at a time from stdin @@ -194,79 +216,80 @@ } else { FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + n = fhc->read(buffer, length); } #ifdef __ARMCC_VERSION return length-n; #else return n; -#endif +#endif } #ifdef __ARMCC_VERSION extern "C" int PREFIX(_istty)(FILEHANDLE fh) #else -extern "C" int isatty(FILEHANDLE fh) +extern "C" int _isatty(FILEHANDLE fh) #endif { /* stdin, stdout and stderr should be tty */ if (fh < 3) return 1; - + FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + return fhc->isatty(); } -#ifdef __ARMCC_VERSION -extern "C" int PREFIX(_seek)(FILEHANDLE fh, long position) { - if (fh < 3) return 0; - - FileHandle* fhc = filehandles[fh-3]; - if (fhc == NULL || fhc->lseek(position, SEEK_SET) == -1) return -1; - - return 0; -} +extern "C" +#if defined(__ARMCC_VERSION) +int _sys_seek(FILEHANDLE fh, long position) +#elif defined(__ICCARM__) +long __lseek(int fh, long offset, int whence) #else -extern "C" int _lseek(FILEHANDLE fh, int offset, int whence) { +int _lseek(FILEHANDLE fh, int offset, int whence) +#endif +{ if (fh < 3) return 0; - - FileHandle *fhc = filehandles[fh-3]; + + FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + +#if defined(__ARMCC_VERSION) + return fhc->lseek(position, SEEK_SET); +#else return fhc->lseek(offset, whence); +#endif } -#endif #ifdef __ARMCC_VERSION extern "C" int PREFIX(_ensure)(FILEHANDLE fh) { if (fh < 3) return 0; - + FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + return fhc->fsync(); } extern "C" long PREFIX(_flen)(FILEHANDLE fh) { if (fh < 3) return 0; - + FileHandle* fhc = filehandles[fh-3]; if (fhc == NULL) return -1; - + return fhc->flen(); } #endif -#ifndef __ARMCC_VERSION +#if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) extern "C" int _fstat(int fd, struct stat *st) { if ((STDOUT_FILENO == fd) || (STDERR_FILENO == fd) || (STDIN_FILENO == fd)) { st->st_mode = S_IFCHR; return 0; } - + errno = EBADF; return -1; } @@ -277,7 +300,7 @@ FilePath fp(path); FileSystemLike *fs = fp.fileSystem(); if (fs == NULL) return -1; - + return fs->remove(fp.fileName()); } @@ -305,11 +328,11 @@ if (path[0] == '/' && path[1] == 0) { return FileSystemLike::opendir(); } - + FilePath fp(path); FileSystemLike* fs = fp.fileSystem(); if (fs == NULL) return NULL; - + return fs->opendir(fp.fileName()); } @@ -337,7 +360,7 @@ FilePath fp(path); FileSystemLike *fs = fp.fileSystem(); if (fs == NULL) return -1; - + return fs->mkdir(fp.fileName(), mode); }