XDK API  3.6.0
Documentation
Data Structures | Macros | Functions | Variables
ff.c File Reference
#include "ff.h"
#include "diskio.h"
#include <stdarg.h>
+ Include dependency graph for ff.c:

Data Structures

struct  putbuff
 

Macros

#define _DF1E   0x9F /* DBC 1st byte range 1 end */
 
#define _DF1S   0x81 /* DBC 1st byte range 1 start */
 
#define _DF2E   0xFC /* DBC 1st byte range 2 end */
 
#define _DF2S   0xE0 /* DBC 1st byte range 2 start */
 
#define _DS1E   0x7E /* DBC 2nd byte range 1 end */
 
#define _DS1S   0x40 /* DBC 2nd byte range 1 start */
 
#define _DS2E   0xFC /* DBC 2nd byte range 2 end */
 
#define _DS2S   0x80 /* DBC 2nd byte range 2 start */
 
#define ABORT(fs, res)   { fp->err = (BYTE)(res); LEAVE_FF(fs, res); }
 
#define BPB_BkBootSec   50 /* Offset of backup boot sector (2) */
 
#define BPB_BytsPerSec   11 /* Sector size [byte] (2) */
 
#define BPB_ExtFlags   40 /* Extended flags (2) */
 
#define BPB_FATSz16   22 /* FAT size [sector] (2) */
 
#define BPB_FATSz32   36 /* FAT size [sector] (4) */
 
#define BPB_FSInfo   48 /* Offset of FSINFO sector (2) */
 
#define BPB_FSVer   42 /* File system version (2) */
 
#define BPB_HiddSec   28 /* Number of special hidden sectors (4) */
 
#define BPB_Media   21 /* Media descriptor (1) */
 
#define BPB_NumFATs   16 /* Number of FAT copies (1) */
 
#define BPB_NumHeads   26 /* Number of heads (2) */
 
#define BPB_RootClus   44 /* Root directory first cluster (4) */
 
#define BPB_RootEntCnt   17 /* Number of root directory entries for FAT12/16 (2) */
 
#define BPB_RsvdSecCnt   14 /* Size of reserved area [sector] (2) */
 
#define BPB_SecPerClus   13 /* Cluster size [sector] (1) */
 
#define BPB_SecPerTrk   24 /* Track size [sector] (2) */
 
#define BPB_TotSec16   19 /* Volume size [sector] (2) */
 
#define BPB_TotSec32   32 /* Volume size [sector] (4) */
 
#define BS_55AA   510 /* Signature word (2) */
 
#define BS_BootSig   38 /* Extended boot signature (1) */
 
#define BS_BootSig32   66 /* Extended boot signature (1) */
 
#define BS_DrvNum   36 /* Physical drive number (1) */
 
#define BS_DrvNum32   64 /* Physical drive number (1) */
 
#define BS_FilSysType   54 /* File system type (1) */
 
#define BS_FilSysType32   82 /* File system type (1) */
 
#define BS_jmpBoot   0 /* x86 jump instruction (3) */
 
#define BS_NTres   37 /* Error flag (1) */
 
#define BS_NTres32   65 /* Error flag (1) */
 
#define BS_OEMName   3 /* OEM name (8) */
 
#define BS_VolID   39 /* Volume serial number (4) */
 
#define BS_VolID32   67 /* Volume serial number (4) */
 
#define BS_VolLab   43 /* Volume label (8) */
 
#define BS_VolLab32   71 /* Volume label (8) */
 
#define DDEM   0xE5 /* Deleted directory entry mark at DIR_Name[0] */
 
#define DEFINE_NAMEBUF   BYTE sfn[12]; WCHAR lbuf[_MAX_LFN + 1]
 
#define DIR_Attr   11 /* Attribute (1) */
 
#define DIR_CrtDate   16 /* Created date (2) */
 
#define DIR_CrtTime   14 /* Created time (2) */
 
#define DIR_CrtTimeTenth   13 /* Created time sub-second (1) */
 
#define DIR_FileSize   28 /* File size (4) */
 
#define DIR_FstClusHI   20 /* Higher 16-bit of first cluster (2) */
 
#define DIR_FstClusLO   26 /* Lower 16-bit of first cluster (2) */
 
#define DIR_LstAccDate   18 /* Last accessed date (2) */
 
#define DIR_Name   0 /* Short file name (11) */
 
#define DIR_NTres   12 /* Lower case flag (1) */
 
#define DIR_WrtDate   24 /* Modified date (2) */
 
#define DIR_WrtTime   22 /* Modified time (2) */
 
#define ENTER_FF(fs)   { if (!lock_fs(fs)) return FR_TIMEOUT; }
 
#define FREE_BUF()
 
#define FSI_Free_Count   488 /* FSI: Number of free clusters (4) */
 
#define FSI_LeadSig   0 /* FSI: Leading signature (4) */
 
#define FSI_Nxt_Free   492 /* FSI: Last allocated cluster (4) */
 
#define FSI_StrucSig   484 /* FSI: Structure signature (4) */
 
#define GET_FATTIME()   get_fattime()
 
#define INIT_BUF(dobj)   { (dobj).fn = sfn; (dobj).lfn = lbuf; }
 
#define IsDBCS1(c)   (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
 
#define IsDBCS2(c)   (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
 
#define IsDigit(c)   (((c)>='0')&&((c)<='9'))
 
#define IsLower(c)   (((c)>='a')&&((c)<='z'))
 
#define IsUpper(c)   (((c)>='A')&&((c)<='Z'))
 
#define LDIR_Attr   11 /* LFN attribute (1) */
 
#define LDIR_Chksum   13 /* Checksum of corresponding SFN entry */
 
#define LDIR_FstClusLO   26 /* Must be zero (0) */
 
#define LDIR_Ord   0 /* LFN entry order and LLE flag (1) */
 
#define LDIR_Type   12 /* LFN type (1) */
 
#define LEAVE_FF(fs, res)   { unlock_fs(fs, res); return res; }
 
#define LLEF   0x40 /* Last long entry flag in LDIR_Ord */
 
#define MBR_Table   446 /* MBR: Partition table offset (2) */
 
#define MIN_FAT16   4086U /* Minimum number of clusters of FAT16 */
 
#define MIN_FAT32   65526U /* Minimum number of clusters of FAT32 */
 
#define N_FATS   1 /* Number of FATs (1 or 2) */
 
#define N_ROOTDIR   512 /* Number of root directory entries for FAT12/16 */
 
#define NS_BODY   0x08 /* Lower case flag (body) */
 
#define NS_DOT   0x20 /* Dot entry */
 
#define NS_EXT   0x10 /* Lower case flag (ext) */
 
#define NS_LAST   0x04 /* Last segment */
 
#define NS_LFN   0x02 /* Force to create LFN entry */
 
#define NS_LOSS   0x01 /* Out of 8.3 format */
 
#define NSFLAG   11 /* Index of name status byte in fn[] */
 
#define RDDEM   0x05 /* Replacement of the character collides with DDEM */
 
#define SS(fs)   ((UINT)_MAX_SS) /* Fixed sector size */
 
#define SZ_DIRE   32 /* Size of a directory entry */
 
#define SZ_PTE   16 /* MBR: Size of a partition table entry */
 

Functions

static BYTE check_fs (FATFS *fs, DWORD sect)
 
static int chk_chr (const char *str, int chr)
 
DWORD clust2sect (FATFS *fs, DWORD clst)
 
static int cmp_lfn (WCHAR *lfnbuf, BYTE *dir)
 
static DWORD create_chain (FATFS *fs, DWORD clst)
 
static FRESULT create_name (DIR *dp, const TCHAR **path)
 
static FRESULT dir_alloc (DIR *dp, UINT nent)
 
static FRESULT dir_find (DIR *dp)
 
static FRESULT dir_next (DIR *dp, int stretch)
 
static FRESULT dir_read (DIR *dp, int vol)
 
static FRESULT dir_register (DIR *dp)
 
static FRESULT dir_remove (DIR *dp)
 
static FRESULT dir_sdi (DIR *dp, UINT idx)
 
FRESULT f_chmod (const TCHAR *path, BYTE attr, BYTE mask)
 The f_chmod function changes the attribute of a file or sub-directory. More...
 
FRESULT f_close (FIL *fp)
 The f_close function closes an open file. More...
 
FRESULT f_closedir (DIR *dp)
 The f_closedir function closes an open directory. More...
 
FRESULT f_getfree (const TCHAR *path, DWORD *nclst, FATFS **fatfs)
 The f_getfree function gets number of the free clusters on the volume. More...
 
TCHARf_gets (TCHAR *buff, int len, FIL *fp)
 The f_gets reads a string from the file. More...
 
FRESULT f_lseek (FIL *fp, DWORD ofs)
 The f_lseek function moves the file read/write pointer of an open file object. It can also be used to expand the file size (cluster pre-allocation). More...
 
FRESULT f_mkdir (const TCHAR *path)
 The f_mkdir function creates a new directory. More...
 
FRESULT f_mkfs (const TCHAR *path, BYTE sfd, UINT au)
 The f_mkfs fucntion creates an FAT file system on the logical drive. More...
 
FRESULT f_mount (FATFS *fs, const TCHAR *path, BYTE opt)
 The f_mount fucntion registers/unregisters file system object to the FatFs module. More...
 
FRESULT f_open (FIL *fp, const TCHAR *path, BYTE mode)
 The f_open function creates a file object to be used to access the file. More...
 
FRESULT f_opendir (DIR *dp, const TCHAR *path)
 The f_opendir function opens a directory. More...
 
int f_printf (FIL *fp, const TCHAR *fmt,...)
 The f_printf function writes formatted string to the file. More...
 
int f_putc (TCHAR c, FIL *fp)
 The f_putc funciton puts a character to the file. More...
 
int f_puts (const TCHAR *str, FIL *fp)
 The f_puts function writes a string to the file. More...
 
FRESULT f_read (FIL *fp, void *buff, UINT btr, UINT *br)
 The f_read function reads data from a file. More...
 
FRESULT f_readdir (DIR *dp, FILINFO *fno)
 The f_readdir function reads directory entries. More...
 
FRESULT f_rename (const TCHAR *path_old, const TCHAR *path_new)
 Renames a file or sub-directory. More...
 
FRESULT f_stat (const TCHAR *path, FILINFO *fno)
 The f_stat function checks the existence of a file or sub-directory. More...
 
FRESULT f_sync (FIL *fp)
 The f_sync function flushes the cached information of a writing file. More...
 
FRESULT f_truncate (FIL *fp)
 The f_truncate function truncates the file size. More...
 
FRESULT f_unlink (const TCHAR *path)
 The f_unlink function removes a file or sub-directory. More...
 
FRESULT f_utime (const TCHAR *path, const FILINFO *fno)
 The f_utime function changes the timestamp of a file or sub-directory. More...
 
FRESULT f_write (FIL *fp, const void *buff, UINT btw, UINT *bw)
 The f_write writes data to a file. More...
 
static FRESULT find_volume (FATFS **rfs, const TCHAR **path, BYTE wmode)
 
static void fit_lfn (const WCHAR *lfnbuf, BYTE *dir, BYTE ord, BYTE sum)
 
static FRESULT follow_path (DIR *dp, const TCHAR *path)
 
static void gen_numname (BYTE *dst, const BYTE *src, const WCHAR *lfn, UINT seq)
 
DWORD get_fat (FATFS *fs, DWORD clst)
 
static void get_fileinfo (DIR *dp, FILINFO *fno)
 
static int get_ldnumber (const TCHAR **path)
 
static DWORD ld_clust (FATFS *fs, const BYTE *dir)
 
static int lock_fs (FATFS *fs)
 
static int mem_cmp (const void *dst, const void *src, UINT cnt)
 
static void mem_cpy (void *dst, const void *src, UINT cnt)
 
static void mem_set (void *dst, int val, UINT cnt)
 
static FRESULT move_window (FATFS *fs, DWORD sector)
 
static int pick_lfn (WCHAR *lfnbuf, BYTE *dir)
 
FRESULT put_fat (FATFS *fs, DWORD clst, DWORD val)
 
static void putc_bfd (putbuff *pb, TCHAR c)
 
static FRESULT remove_chain (FATFS *fs, DWORD clst)
 
static void st_clust (BYTE *dir, DWORD cl)
 
static BYTE sum_sfn (const BYTE *dir)
 
static FRESULT sync_fs (FATFS *fs)
 
static FRESULT sync_window (FATFS *fs)
 
static void unlock_fs (FATFS *fs, FRESULT res)
 
static FRESULT validate (void *obj)
 

Variables

static FATFSFatFs [_VOLUMES]
 
static WORD Fsid
 
static const BYTE LfnOfs [] = {1,3,5,7,9,14,16,18,20,22,24,28,30}
 

Macro Definition Documentation

#define _DF1E   0x9F /* DBC 1st byte range 1 end */
#define _DF1S   0x81 /* DBC 1st byte range 1 start */
#define _DF2E   0xFC /* DBC 1st byte range 2 end */
#define _DF2S   0xE0 /* DBC 1st byte range 2 start */
#define _DS1E   0x7E /* DBC 2nd byte range 1 end */
#define _DS1S   0x40 /* DBC 2nd byte range 1 start */
#define _DS2E   0xFC /* DBC 2nd byte range 2 end */
#define _DS2S   0x80 /* DBC 2nd byte range 2 start */
#define ABORT (   fs,
  res 
)    { fp->err = (BYTE)(res); LEAVE_FF(fs, res); }
#define BPB_BkBootSec   50 /* Offset of backup boot sector (2) */
#define BPB_BytsPerSec   11 /* Sector size [byte] (2) */
#define BPB_ExtFlags   40 /* Extended flags (2) */
#define BPB_FATSz16   22 /* FAT size [sector] (2) */
#define BPB_FATSz32   36 /* FAT size [sector] (4) */
#define BPB_FSInfo   48 /* Offset of FSINFO sector (2) */
#define BPB_FSVer   42 /* File system version (2) */
#define BPB_HiddSec   28 /* Number of special hidden sectors (4) */
#define BPB_Media   21 /* Media descriptor (1) */
#define BPB_NumFATs   16 /* Number of FAT copies (1) */
#define BPB_NumHeads   26 /* Number of heads (2) */
#define BPB_RootClus   44 /* Root directory first cluster (4) */
#define BPB_RootEntCnt   17 /* Number of root directory entries for FAT12/16 (2) */
#define BPB_RsvdSecCnt   14 /* Size of reserved area [sector] (2) */
#define BPB_SecPerClus   13 /* Cluster size [sector] (1) */
#define BPB_SecPerTrk   24 /* Track size [sector] (2) */
#define BPB_TotSec16   19 /* Volume size [sector] (2) */
#define BPB_TotSec32   32 /* Volume size [sector] (4) */
#define BS_55AA   510 /* Signature word (2) */
#define BS_BootSig   38 /* Extended boot signature (1) */
#define BS_BootSig32   66 /* Extended boot signature (1) */
#define BS_DrvNum   36 /* Physical drive number (1) */
#define BS_DrvNum32   64 /* Physical drive number (1) */
#define BS_FilSysType   54 /* File system type (1) */
#define BS_FilSysType32   82 /* File system type (1) */
#define BS_jmpBoot   0 /* x86 jump instruction (3) */
#define BS_NTres   37 /* Error flag (1) */
#define BS_NTres32   65 /* Error flag (1) */
#define BS_OEMName   3 /* OEM name (8) */
#define BS_VolID   39 /* Volume serial number (4) */
#define BS_VolID32   67 /* Volume serial number (4) */
#define BS_VolLab   43 /* Volume label (8) */
#define BS_VolLab32   71 /* Volume label (8) */
#define DDEM   0xE5 /* Deleted directory entry mark at DIR_Name[0] */
#define DEFINE_NAMEBUF   BYTE sfn[12]; WCHAR lbuf[_MAX_LFN + 1]
#define DIR_Attr   11 /* Attribute (1) */
#define DIR_CrtDate   16 /* Created date (2) */
#define DIR_CrtTime   14 /* Created time (2) */
#define DIR_CrtTimeTenth   13 /* Created time sub-second (1) */
#define DIR_FileSize   28 /* File size (4) */
#define DIR_FstClusHI   20 /* Higher 16-bit of first cluster (2) */
#define DIR_FstClusLO   26 /* Lower 16-bit of first cluster (2) */
#define DIR_LstAccDate   18 /* Last accessed date (2) */
#define DIR_Name   0 /* Short file name (11) */
#define DIR_NTres   12 /* Lower case flag (1) */
#define DIR_WrtDate   24 /* Modified date (2) */
#define DIR_WrtTime   22 /* Modified time (2) */
#define ENTER_FF (   fs)    { if (!lock_fs(fs)) return FR_TIMEOUT; }
#define FREE_BUF ( )
#define FSI_Free_Count   488 /* FSI: Number of free clusters (4) */
#define FSI_LeadSig   0 /* FSI: Leading signature (4) */
#define FSI_Nxt_Free   492 /* FSI: Last allocated cluster (4) */
#define FSI_StrucSig   484 /* FSI: Structure signature (4) */
#define GET_FATTIME ( )    get_fattime()
#define INIT_BUF (   dobj)    { (dobj).fn = sfn; (dobj).lfn = lbuf; }
#define IsDBCS1 (   c)    (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
#define IsDBCS2 (   c)    (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
#define IsDigit (   c)    (((c)>='0')&&((c)<='9'))
#define IsLower (   c)    (((c)>='a')&&((c)<='z'))
#define IsUpper (   c)    (((c)>='A')&&((c)<='Z'))
#define LDIR_Attr   11 /* LFN attribute (1) */
#define LDIR_Chksum   13 /* Checksum of corresponding SFN entry */
#define LDIR_FstClusLO   26 /* Must be zero (0) */
#define LDIR_Ord   0 /* LFN entry order and LLE flag (1) */
#define LDIR_Type   12 /* LFN type (1) */
#define LEAVE_FF (   fs,
  res 
)    { unlock_fs(fs, res); return res; }
#define LLEF   0x40 /* Last long entry flag in LDIR_Ord */
#define MBR_Table   446 /* MBR: Partition table offset (2) */
#define MIN_FAT16   4086U /* Minimum number of clusters of FAT16 */
#define MIN_FAT32   65526U /* Minimum number of clusters of FAT32 */
#define N_FATS   1 /* Number of FATs (1 or 2) */
#define N_ROOTDIR   512 /* Number of root directory entries for FAT12/16 */
#define NS_BODY   0x08 /* Lower case flag (body) */
#define NS_DOT   0x20 /* Dot entry */
#define NS_EXT   0x10 /* Lower case flag (ext) */
#define NS_LAST   0x04 /* Last segment */
#define NS_LFN   0x02 /* Force to create LFN entry */
#define NS_LOSS   0x01 /* Out of 8.3 format */
#define NSFLAG   11 /* Index of name status byte in fn[] */
#define RDDEM   0x05 /* Replacement of the character collides with DDEM */
#define SS (   fs)    ((UINT)_MAX_SS) /* Fixed sector size */
#define SZ_DIRE   32 /* Size of a directory entry */
#define SZ_PTE   16 /* MBR: Size of a partition table entry */

Function Documentation

static BYTE check_fs ( FATFS fs,
DWORD  sect 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int chk_chr ( const char *  str,
int  chr 
)
static

+ Here is the caller graph for this function:

DWORD clust2sect ( FATFS fs,
DWORD  clst 
)

+ Here is the caller graph for this function:

static int cmp_lfn ( WCHAR lfnbuf,
BYTE dir 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static DWORD create_chain ( FATFS fs,
DWORD  clst 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT create_name ( DIR dp,
const TCHAR **  path 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT dir_alloc ( DIR dp,
UINT  nent 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT dir_find ( DIR dp)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT dir_next ( DIR dp,
int  stretch 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT dir_read ( DIR dp,
int  vol 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT dir_register ( DIR dp)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT dir_remove ( DIR dp)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT dir_sdi ( DIR dp,
UINT  idx 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT find_volume ( FATFS **  rfs,
const TCHAR **  path,
BYTE  wmode 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void fit_lfn ( const WCHAR lfnbuf,
BYTE dir,
BYTE  ord,
BYTE  sum 
)
static

+ Here is the caller graph for this function:

static FRESULT follow_path ( DIR dp,
const TCHAR path 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void gen_numname ( BYTE dst,
const BYTE src,
const WCHAR lfn,
UINT  seq 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

DWORD get_fat ( FATFS fs,
DWORD  clst 
)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void get_fileinfo ( DIR dp,
FILINFO fno 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int get_ldnumber ( const TCHAR **  path)
static

+ Here is the caller graph for this function:

static DWORD ld_clust ( FATFS fs,
const BYTE dir 
)
static

+ Here is the caller graph for this function:

static int lock_fs ( FATFS fs)
static

+ Here is the call graph for this function:

static int mem_cmp ( const void *  dst,
const void *  src,
UINT  cnt 
)
static

+ Here is the caller graph for this function:

static void mem_cpy ( void *  dst,
const void *  src,
UINT  cnt 
)
static

+ Here is the caller graph for this function:

static void mem_set ( void *  dst,
int  val,
UINT  cnt 
)
static

+ Here is the caller graph for this function:

static FRESULT move_window ( FATFS fs,
DWORD  sector 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int pick_lfn ( WCHAR lfnbuf,
BYTE dir 
)
static

+ Here is the caller graph for this function:

FRESULT put_fat ( FATFS fs,
DWORD  clst,
DWORD  val 
)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void putc_bfd ( putbuff pb,
TCHAR  c 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT remove_chain ( FATFS fs,
DWORD  clst 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void st_clust ( BYTE dir,
DWORD  cl 
)
static

+ Here is the caller graph for this function:

static BYTE sum_sfn ( const BYTE dir)
static

+ Here is the caller graph for this function:

static FRESULT sync_fs ( FATFS fs)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT sync_window ( FATFS fs)
static

+ Here is the caller graph for this function:

static void unlock_fs ( FATFS fs,
FRESULT  res 
)
static

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static FRESULT validate ( void *  obj)
static

+ Here is the caller graph for this function:

Variable Documentation

FATFS* FatFs[_VOLUMES]
static
WORD Fsid
static
const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}
static

All rights reserved. The use is subject to the XDK SDK EULA by Bosch Connected Devices and Solutions GmbH.
This documentation file has been automatically generated on Thu Mar 14 2019 19:12:45 by doxygen 1.8.8