diff --git a/.gitignore b/.gitignore index 2a876a1..64a08e6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ /lib*.dll* /man +/docs/_build + .*.swp diff --git a/Makefile b/Makefile index 04e2732..e203846 100755 --- a/Makefile +++ b/Makefile @@ -8,14 +8,14 @@ include Makefile.vars Makefile.msg # General targets # #*****************************************************************************# # Build everything. -all: all-lib $(if $(INSTALL_MANPAGES),all-doc) +all: all-lib # Mostly clean everything (remove everything but the end results). -mostlyclean: mostlyclean-lib mostlyclean-doc +mostlyclean: mostlyclean-lib mclean: mostlyclean # Clean everything. -clean: clean-lib clean-doc +clean: clean-lib fclean: clean # To original state. @@ -29,10 +29,10 @@ mrproper: clean re: clean all # Install everything. -install: install-lib $(if $(INSTALL_MANPAGES),install-doc) +install: install-lib # Uninstall everything. (experimental) -uninstall: uninstall-lib uninstall-doc +uninstall: uninstall-lib # Reinstall everything. (experimental) reinstall: uninstall install @@ -212,66 +212,11 @@ $(eval $(call make-obj-rule,$(src)))) .PHONY: install-cfgtool uninstall-cfgtool #*****************************************************************************# -# Documentation-related # +# Documentation-related targets # #*****************************************************************************# -# Make all manpages. - all-doc: $(foreach s,$(MAN_SECTIONS), $(MAN_$(s):%=$(MANDIR)/man$(s)/%.$(s))) +# Make the HTML documentation. +html: + @sphinx-build -b html docs docs/_build/html -# Make manpages directories. - $(MAN_SECTIONS:%=$(MANDIR)/man%): - $(call bcmd,mkdir,$@,$(MD) $@) - -# Make a manpage. -define make-manpage-rule - $(MANDIR)/man$1/%.$1: $(DOCDIR)/%.$1.txt | $(MANDIR)/man$1 - $(call bcmd,a2x,$$<,$(A2X) -f manpage -D $$| $$< 2>/dev/null) -endef -$(foreach section, $(MAN_SECTIONS), \ -$(eval $(call make-manpage-rule,$(section)))) - -# Mostly clean (do nothing, really) - mostlyclean-doc: - mclean-doc: mostlyclean-doc - -# Remove all built manpages. - clean-doc: - $(call rmsg,Removing manpages directory.) - $(call qcmd,$(RM) -r $(MANDIR)) - -# Remake all manpages. -# (I don't really know why some people would want to do that though) - re-doc: clean-doc all-doc - -# Install a manpages section. -define make-installmansection-rule - install-doc-$1: $(MAN_$1:%=$(MANDIR)/man$1/%.$1) - $(call imsg,Installing manpages section $1.) - $(call qcmd,$(INST) -m 755 -d "$(IMANDIR)/man$1") - $(call qcmd,$(INST) -m 644 -t "$(IMANDIR)/man$1" \ - $(MAN_$1:%=$(MANDIR)/man$1/%.$1)) - $(call qcmd,$(GZIP) $(MAN_$1:%="$(IMANDIR)/man$1/%.$1")) -endef -$(foreach section, $(MAN_SECTIONS), \ -$(eval $(call make-installmansection-rule,$(section)))) - -# Install manpages. - install-doc: $(CHECKCFG) $(MAN_SECTIONS:%=install-doc-%) - -# Clean a manpages section. -define make-uninstall-doc-rule - uninstall-doc-$1: - $(call rmsg,Uninstalling manpages section $1.) - $(call qcmd,$(RM) "$(IMANDIR)/man$1/lib$(NAME).$1"* \ - "$(IMANDIR)/man$1/$(NAME)_"*".$1"* \ - "$(IMANDIR)/man$1/lib$(NAME)-config.$1"*) -endef -$(foreach sec,$(MAN_SECTIONS), \ -$(eval $(call make-uninstall-doc-rule,$(sec)))) - -# Uninstall manpages - uninstall-doc: $(CHECKCFG) $(MAN_SECTIONS:%=uninstall-doc-%) - -.PHONY: all-doc mostlyclean-doc mclean-doc clean-doc re-doc -.PHONY: install-doc uninstall-doc -.PHONY: $(foreach s,$(MAN_SECTIONS),install-doc-$(s) uninstall-doc-$(s)) +.PHONY: html # End of file diff --git a/configure b/configure index 639e5d4..4ad65f2 100755 --- a/configure +++ b/configure @@ -41,10 +41,8 @@ hbindir='${hprefix}/bin' libdir='${prefix}/lib'"$platform" includedir='${prefix}/include'"$platform" pkgdir='${libdir}/pkgconfig' -mandir='${prefix}/share/man' # Installation options -install_manpages=yes install_devel=yes # Tweaks @@ -77,7 +75,6 @@ Build options: --loglevel=LOGLEVEL default library log level [$loglevel] Installation options: - --no-manpages should not make and install manpages --no-devel should not install developement files Installation directories: @@ -91,7 +88,6 @@ Fine tuning of the installation directories: --pkgdir=PKGDIR pkg-config configurations directory [$pkgdir] --libdir=LIBDIR library files of the linker [$libdir] --includedir=INCDIR include files for the compiler [$includedir] - --mandir=MANDIR man root [$mandir] Other tweaks: CFLAGS=CFLAGS some more compilation flags @@ -131,7 +127,7 @@ esac; done #*****************************************************************************# for arg ; do case "$arg" in --make-full-log) make_full_log=yes ;; ---maintainer) more_warnings=yes; loglevel=info; install_manpages= ;; +--maintainer) more_warnings=yes; loglevel=info ;; --target=*) target="${arg#*=}" ;; --static) static=y ;; --windows) windows=y ;; @@ -152,7 +148,6 @@ got '$level'" fi # then set loglevel=$level ;; ---no-manpages) install_manpages= ;; --no-devel) install_devel= ;; --root=*) root="${arg#*=}" ;; --hprefix=*) hprefix="${arg#*=}" ;; @@ -162,7 +157,6 @@ got '$level'" --pkgdir=*) pkgdir="${arg#*=}" ;; --libdir=*) libdir="${arg#*=}" ;; --includedir=*) includedir="${arg#*=}" ;; ---mandir=*) mandir="${arg#*=}" ;; CFLAGS=*) cflags="${arg#*=}" ;; LDFLAGS=*) ldflags="${arg#*=}" ;; *) echo "$arg: didn't read" ;; @@ -182,7 +176,7 @@ case "$target" in *-mingw32) if [ ! "$static" ]; then fi;; esac # Evaluate variables -vars="prefix bindir libdir pkgdir includedir mandir hprefix hbindir" +vars="prefix bindir libdir pkgdir includedir hprefix hbindir" for var in $vars; do eval $var'='$(eval 'echo $'$var) done @@ -261,10 +255,8 @@ cat < - -/* TODO */ ----- - -DESCRIPTION ------------ -TODO. diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..43ecfda --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# libcasio documentation build configuration file, created by +# sphinx-quickstart on Fri Jul 7 02:37:36 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'libcasio' +copyright = '2017, Thomas "Cakeisalie5" Touhey' +author = 'Thomas "Cakeisalie5" Touhey' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.1' +# The full version, including alpha/beta/rc tags. +release = '0.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + 'donate.html', + ] +} + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'libcasiodoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'libcasio.tex', 'libcasio docs', + 'Thomas "Cakeisalie5" Touhey', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'libcasio', 'libcasio docs', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'libcasio', 'libcasio docs', + author, 'libcasio', 'Library for manipulating CASIO-related elements.', + 'Miscellaneous'), +] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..8e8bf4b --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,23 @@ +Welcome to libcasio's documentation! +==================================== +.. rubric:: Everything you need to know about libcasio. + +libcasio ought to become the *de facto* standard when it comes to manipulating +protocols and file formats used with CASIO calculators. +Most of it is platform-agnostic, although it contains stream and filesystem +interfaces with the most commons systems such as Microsoft Windows, +GNU/Linux distributions or Apple's OS X. + +.. note:: + The C "namespace" the library reserves are `casio_`, `CASIO_`, `libcasio_` + and `LIBCASIO_`; consider the usage of anything starting with one of those + prefixes as having an undefined behaviour + (so you really shoundn't do that). + +There are many objects in libcasio. Choose what fits your need! + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + stream.rst diff --git a/docs/stream.rst b/docs/stream.rst new file mode 100644 index 0000000..8f0ebca --- /dev/null +++ b/docs/stream.rst @@ -0,0 +1,53 @@ +libcasio streams +================ + +When it wasn't libcasio yet (at the time, communication-related objects were +in libp7), libusb usage used to be hardcoded in the Protocol 7.00 management +functions (sending, receiving); then, it used FILE streams from the GNU libc +implementation, but that still wasn't platform-agnostic enough, so what has +finally be decided is that the library would use its own stream object. + +This stream object is usable both by the library and by the user. +The library defines some useful platform-agnostic streams it uses itself, +such as the checksum stream (which calculates the checksum as the file content +is read), and some platform-specific streams, related to POSIX or +the Windows API for example. It should only implement platform-specific +streams for platforms defining a macro (for example, CASIOWIN doesn't!). + +This document describes how to use and make a libcasio stream. + +Opening and closing +------------------- + +There are three ways to open a stream: + +- with a specialized function, such as :code:`casio_open_stream_streams()` + for POSIX or :code:`casio_opencom_windows()` for the Windows API; +- with a multi-stream function, such as :code:`casio_open_usb_stream()` + for USB-connected calculators, or :code:`casio_open_com_stream()` for + serial-connected calculators; +- with the core function, :code:`casio_open_stream()`, which you will use + when you will want to define your own streams. + +All of the stream opening function shall take a reference to the stream pointer +you'll use as the stream handle as the first parameter, and return the libcasio +error code that occured (or 0 if no error has occured). + +Once you are done with the stream, you shall close it, so that all of the +allocated resources can be free'd properly. In order to do this, you can +simply use :code:`casio_close()`. So here's a simple example using +the :code:`casio_open_memory()` function (which makes a stream out of memory): + +.. code-block:: c + :linenos: + + int err; + casio_stream_t *stream; + + err = casio_open_memory(&stream, my_memory_area, the_memory_area_size); + if (err) { /* oh no, things went wrong... */ } + + /* make awesome things */ + + err = casio_close(stream); + if (err) { /* things went wrong, but that's alright */ } diff --git a/include/libcasio/cdefs.h b/include/libcasio/cdefs.h index 0b9adc3..4ea5144 100644 --- a/include/libcasio/cdefs.h +++ b/include/libcasio/cdefs.h @@ -69,6 +69,18 @@ # define OF(CASIO_ARGS) () # endif /* ************************************************************************* */ +/* Enumerations */ +/* ************************************************************************* */ +/* Enumerations can be great thanks to the compiler: better warnings, + * better debug, better coding! */ + +# if defined(LIBCASIO_USE_ENUMS) +# elif defined(__STDC__) && __STDC__ +# define LIBCASIO_USE_ENUMS 1 +# else /* K&R C, no enums! */ +# define LIBCASIO_USE_ENUMS 0 +# endif +/* ************************************************************************* */ /* C++ declarations and namespaces management */ /* ************************************************************************* */ /* libcasio is made in C. */ diff --git a/include/libcasio/fs.h b/include/libcasio/fs.h index 24c50a4..8610fb5 100644 --- a/include/libcasio/fs.h +++ b/include/libcasio/fs.h @@ -20,6 +20,7 @@ # define LIBCASIO_FS_H # include "cdefs.h" # include "stream.h" +# include CASIO_BEGIN_NAMESPACE /* forward structure declarations (don't mind) */ @@ -49,6 +50,16 @@ struct casio_pathnode_s { unsigned char casio_pathnode_name[2048]; }; +/* Path nodes should be managed using the following functions: */ + +CASIO_EXTERN int CASIO_EXPORT casio_make_pathnode + OF((casio_pathnode_t **casio__node, size_t casio__size)); +CASIO_EXTERN void CASIO_EXPORT casio_free_pathnode + OF((casio_pathnode_t *casio__node)); +CASIO_EXTERN int CASIO_EXPORT casio_duplicate_pathnode + OF((casio_pathnode_t **casio__new_node, + const casio_pathnode_t *casio__old_node)); + /* And here is the main path structure. */ #define casio_pathflag_alloc 0x0001 /* path object is valid and allocated */ @@ -63,29 +74,92 @@ struct casio_path_s { /* Filesystem file entry */ /* ************************************************************************* */ /* This structure defines file metadata. - * Here are the flags: */ + * Here are the flags: + * `CASIO_STAT_FLAG_PERM`: stat permissions are set; + * `CASIO_STAT_FLAG_BTIME`: birth time is set; + * `CASIO_STAT_FLAG_ATIME`: last accessed time is set; + * `CASIO_STAT_FLAG_MTIME`: last modif. time is set. */ -/* TODO */ +# define CASIO_STAT_FLAG_PERM 0x0001 +# define CASIO_STAT_FLAG_BTIME 0x0002 +# define CASIO_STAT_FLAG_ATIME 0x0004 +# define CASIO_STAT_FLAG_MTIME 0x0008 + +/* Elements can have Unix-like permissions. Here they are: + * `CASIO_STAT_PERM_IRUSR`: user has read permission; + * `CASIO_STAT_PERM_IWUSR`: user has write permission; + * `CASIO_STAT_PERM_IXUSR`: user has exec permission; + * `CASIO_STAT_PERM_IRGRP`: group has read permission; + * `CASIO_STAT_PERM_IWGRP`: group has write permission; + * `CASIO_STAT_PERM_IXGRP`: group has exec permission; + * `CASIO_STAT_PERM_IROTH`: others have read permission; + * `CASIO_STAT_PERM_IWOTH`: others have write permission; + * `CASIO_STAT_PERM_IXOTH`: others have exec permission. */ + +# define CASIO_STAT_PERM_IRUSR 0x0001 +# define CASIO_STAT_PERM_IWUSR 0x0002 +# define CASIO_STAT_PERM_IXUSR 0x0004 +# define CASIO_STAT_PERM_IRGRP 0x0010 +# define CASIO_STAT_PERM_IWGRP 0x0020 +# define CASIO_STAT_PERM_IXGRP 0x0040 +# define CASIO_STAT_PERM_IROTH 0x0100 +# define CASIO_STAT_PERM_IWOTH 0x0200 +# define CASIO_STAT_PERM_IXOTH 0x0400 /* And here are the "file" types ("file" is between quotes as on Windows, - * directories are not files like on Unix) you can find: */ + * directories are not files like on Unix) you can find: + * `CASIO_STAT_TYPE_REG`: regular file; + * `CASIO_STAT_TYPE_DIR`: directory; + * `CASIO_STAT_TYPE_LNK`: symbolic link; + * `CASIO_STAT_TYPE_CHAR`: character device; + * `CASIO_STAT_TYPE_BLK`: block device; + * `CASIO_STAT_TYPE_SOCK`: socket */ -# define CASIO_STAT_TYPE_REG 0x0001 /* Regular file. */ -# define CASIO_STAT_TYPE_DIR 0x0002 /* Directory. */ -# define CASIO_STAT_TYPE_LNK 0x0004 /* Symbolic link. */ -# define CASIO_STAT_TYPE_CHAR 0x0008 /* Character device. */ -# define CASIO_STAT_TYPE_BLK 0x0010 /* Block device. */ -# define CASIO_STAT_TYPE_SOCK 0x0020 /* Socket. */ +# define CASIO_STAT_TYPE_REG 0x0001 +# define CASIO_STAT_TYPE_DIR 0x0002 +# define CASIO_STAT_TYPE_LNK 0x0004 +# define CASIO_STAT_TYPE_CHAR 0x0008 +# define CASIO_STAT_TYPE_BLK 0x0010 +# define CASIO_STAT_TYPE_SOCK 0x0020 -/* And here is the stat structure. - * The path is not in it. */ +/* And here is the stat structure. The elements it contains at runtime depend + * on the flags (useful for binary compatibility and filesystem metadata type). + * For example, if `~thestat.casio_stat_flags & CASIO_STAT_FLAG_PERM`, + * then you shouldn't try to read the permissions, as it might contain crap. + * + * The elements are the following: + * [ ] `casio_stat_type`: the file type (see the `CASIO_STAT_TYPE_*` macros); + * [ ] `casio_stat_perm`: Unix-like permissions (see `CASIO_STAT_PERM_*`); + * [X] `casio_stat_size`: the file size; + * [X] `casio_stat_btime`: the file's birth time; + * [X] `casio_stat_atime`: the file's last access time; + * [X] `casio_stat_mtime`: the file's last modification time. + * + * Checked elements should not be read without checking that the corresponding + * flag is set (compatibility and filesystem feature reasons). + * + * The file path/name is not in it, because it is: + * - given by yourself when you are querying file information; + * - given beside with listing callbacks. */ struct casio_stat_s { - unsigned int casio_stat_flags; - unsigned int casio_stat_type; - casio_off_t casio_stat_size; + unsigned short casio_stat_flags; + unsigned short casio_stat_type; + unsigned short casio_stat_perm; + unsigned short casio_stat__reserved; + + casio_off_t casio_stat_size; + time_t casio_stat_btime; + time_t casio_stat_atime; + time_t casio_stat_mtime; }; +/* Here is the file listing callback type you will give to `casio_list`. + * + * If you want to copy the path node, do not copy the pointer as it will + * probably disappear afterwards, duplicate the node using + * `casio_duplicate_pathnode`! */ + typedef void casio_fs_list_func_t OF((void *casio__cookie, const casio_pathnode_t *casio__node, const casio_stat_t *casio__stat)); /* ************************************************************************* */ @@ -115,10 +189,17 @@ typedef int casio_fs_stat_t OF((void *casio__cookie, void *casio__native_path, casio_stat_t *casio__stat)); -/* The `casio_fs_makedir` callback is used to create a directory. */ +/* The `casio_fs_make` callback is used to create an element. + * The arguments depend on the file type: + * - `CASIO_STAT_TYPE_REG`: casio_off_t size; + * - `CASIO_STAT_TYPE_LNK`: void *casio__destination_path. */ -typedef int casio_fs_makedir_t - OF((void *casio__cookie, void *casio__native_path)); +# if defined(__STDC__) && __STDC__ +typedef int casio_fs_make_t(void *casio__cookie, + void *casio__native_path, const casio_stat_t *casio__stat, ...); +# else +typedef int casio_fs_make_t(); +# endif /* The `casio_fs_del` callback is used to delete an element of any type * from your filesystem. */ @@ -156,7 +237,7 @@ struct casio_fsfuncs_s { casio_fs_freepath_t *casio_fsfuncs_freepath; casio_fs_stat_t *casio_fsfuncs_stat; - casio_fs_makedir_t *casio_fsfuncs_makedir; + casio_fs_make_t *casio_fsfuncs_make; casio_fs_del_t *casio_fsfuncs_del; casio_fs_move_t *casio_fsfuncs_move; diff --git a/include/libcasio/stream.h b/include/libcasio/stream.h index f97dad2..3a84dba 100644 --- a/include/libcasio/stream.h +++ b/include/libcasio/stream.h @@ -293,11 +293,15 @@ CASIO_EXTERN int CASIO_EXPORT casio_isreadable OF((casio_stream_t *casio__stream)); CASIO_EXTERN int CASIO_EXPORT casio_iswritable OF((casio_stream_t *casio__stream)); +CASIO_EXTERN int CASIO_EXPORT casio_isseekable + OF((casio_stream_t *casio__stream)); # define casio_isreadable(CASIO__STREAM) \ (casio_get_openmode(CASIO__STREAM) & CASIO_OPENMODE_READ) # define casio_iswritable(CASIO__STREAM) \ (casio_get_openmode(CASIO__STREAM) & CASIO_OPENMODE_WRITE) +# define casio_isseekable(CASIO__STREAM) \ + (casio_get_openmode(CASIO__STREAM) & CASIO_OPENMODE_SEEK) CASIO_EXTERN casio_openmode_t CASIO_EXPORT casio_get_openmode OF((casio_stream_t *casio__stream)); diff --git a/src/fs/builtin/posix/del.c b/src/fs/builtin/posix/del.c new file mode 100644 index 0000000..44b3b61 --- /dev/null +++ b/src/fs/builtin/posix/del.c @@ -0,0 +1,50 @@ +/* **************************************************************************** + * fs/builtin/posix/del.c -- delete a POSIX file/directory. + * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3.0 of the License, + * or (at your option) any later version. + * + * libcasio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#define PATHS_FTW +#include "posix.h" +#ifndef LIBCASIO_DISABLED_POSIX + +/** + * casio_posix_delete: + * Delete a file or directory. + * + * @arg cookie the cookie. + * @arg path the file path. + * @return the error code (0 if ok). + */ + +int CASIO_EXPORT casio_posix_delete(void *cookie, const char *path) +{ + int err; + + /* Remove. */ + if (!remove(path)) + return (0); + + /* Get the libcasio error. */ + switch (errno) { + /* TODO */ + default: + err = casio_error_unknown; + } + + return (err); +} + +#endif diff --git a/src/fs/builtin/posix/frompath.c b/src/fs/builtin/posix/frompath.c index 8557d97..427c815 100644 --- a/src/fs/builtin/posix/frompath.c +++ b/src/fs/builtin/posix/frompath.c @@ -16,28 +16,10 @@ * You should have received a copy of the GNU Lesser General Public License * along with libcasio; if not, see . * ************************************************************************* */ +#define PATH_FTW #include "posix.h" #ifndef LIBCASIO_DISABLED_POSIX_FS -/** - * makepathnode: - * Make a directory node. - * - * @arg size the name size. - * @return the allocated path node. - */ - -CASIO_LOCAL casio_pathnode_t *makepathnode(size_t size) -{ - casio_pathnode_t *node; - - node = malloc(offsetof(casio_pathnode_t, casio_pathnode_name) + size); - if (!node) return (NULL); - node->casio_pathnode_next = NULL; - node->casio_pathnode_size = size; - return (node); -} - /** * casio_make_posix_path_array: * Make a path array from a POSIX path. @@ -52,6 +34,7 @@ CASIO_LOCAL casio_pathnode_t *makepathnode(size_t size) int CASIO_EXPORT casio_make_posix_path_array(casio_path_t **ppath, const char *rawpath) { + int err = casio_error_alloc; casio_path_t *path = NULL; casio_pathnode_t **node = NULL; casio_pathnode_t *localnode = NULL; @@ -80,8 +63,8 @@ int CASIO_EXPORT casio_make_posix_path_array(casio_path_t **ppath, nodelen = strcspn(rawpath, "/"); /* Make the entry. */ - localnode = makepathnode(nodelen + 1); - if (!localnode) goto fail; + err = casio_make_pathnode(&localnode, nodelen + 1); + if (err) goto fail; memcpy(localnode->casio_pathnode_name, rawpath, nodelen); localnode->casio_pathnode_name[nodelen] = 0; *node = localnode; @@ -98,7 +81,8 @@ fail: path->casio_path_nodes = localnode->casio_pathnode_next; free(localnode); } - return (casio_error_alloc); + if (!err) err = casio_error_alloc; + return (err); } #endif diff --git a/src/fs/builtin/posix/make.c b/src/fs/builtin/posix/make.c index 44b1495..4438896 100644 --- a/src/fs/builtin/posix/make.c +++ b/src/fs/builtin/posix/make.c @@ -1,5 +1,5 @@ /* **************************************************************************** - * fs/builtin/posix/make.c -- open a POSIX filesystem. + * fs/builtin/posix/make.c -- make a POSIX filesystem element. * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey * * This file is part of libcasio. @@ -16,28 +16,26 @@ * You should have received a copy of the GNU Lesser General Public License * along with libcasio; if not, see . * ************************************************************************* */ +#define PATHS_FTW #include "posix.h" -#ifndef LIBCASIO_DISABLED_POSIX_FS - -/* Callbacks. */ - -CASIO_LOCAL casio_fsfuncs_t posix_fs_funcs = { - NULL, &casio_make_posix_path, &casio_free_posix_path, - &casio_posix_stat, NULL, NULL, NULL, - NULL, NULL -}; +#ifndef LIBCASIO_DISABLED_POSIX /** - * casio_open_posix_fs: - * Open a POSIX filesystem interface. + * casio_posix_make: + * Make a POSIX filesystem element. * - * @arg fs the filesystem interface to make. - * @return the error code (0 if ok). + * @arg cookie the cookie. + * @arg path the file path. + * @arg stat the file information. + * @arg ... other information depending on the file type. + * @return the error code (0 if ok). */ -int CASIO_EXPORT casio_open_posix_fs(casio_fs_t **fs) +int CASIO_EXPORT casio_posix_make(void *cookie, const char *path, + const casio_stat_t *info, ...) { - return (casio_open_fs(fs, NULL, &posix_fs_funcs)); + /* TODO */ + return (casio_error_op); } #endif diff --git a/src/fs/builtin/posix/open_fs.c b/src/fs/builtin/posix/open_fs.c new file mode 100644 index 0000000..c575dff --- /dev/null +++ b/src/fs/builtin/posix/open_fs.c @@ -0,0 +1,43 @@ +/* **************************************************************************** + * fs/builtin/posix/open_fs.c -- open a POSIX filesystem. + * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3.0 of the License, + * or (at your option) any later version. + * + * libcasio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#include "posix.h" +#ifndef LIBCASIO_DISABLED_POSIX_FS + +/* Callbacks. */ + +CASIO_LOCAL casio_fsfuncs_t posix_fs_funcs = { + NULL, &casio_make_posix_path, &casio_free_posix_path, + &casio_posix_stat, NULL, NULL, NULL, + NULL, NULL +}; + +/** + * casio_open_posix_fs: + * Open a POSIX filesystem interface. + * + * @arg fs the filesystem interface to make. + * @return the error code (0 if ok). + */ + +int CASIO_EXPORT casio_open_posix_fs(casio_fs_t **fs) +{ + return (casio_open_fs(fs, NULL, &posix_fs_funcs)); +} + +#endif diff --git a/src/fs/builtin/posix/posix.h b/src/fs/builtin/posix/posix.h index 70f8848..b8a1992 100644 --- a/src/fs/builtin/posix/posix.h +++ b/src/fs/builtin/posix/posix.h @@ -20,15 +20,28 @@ # define LOCAL_FS_BUILTIN_POSIX_H 1 # include "../../../internals.h" # ifndef LIBCASIO_DISABLED_POSIX_FS +# include +# include # include # include +# include +# include + +/* Native type. */ + +# ifdef PATHS_FTW +typedef const char* posix_path_t; +# else +typedef void* posix_path_t; +# endif /* Path conversions. */ CASIO_EXTERN int CASIO_EXPORT casio_make_posix_path - OF((void *casio__cookie, void **casio__path, casio_path_t *casio__array)); + OF((void *casio__cookie, posix_path_t *casio__path, + casio_path_t *casio__array)); CASIO_EXTERN void CASIO_EXPORT casio_free_posix_path - OF((void *casio__cookie, void *casio__path)); + OF((void *casio__cookie, posix_path_t casio__path)); CASIO_EXTERN int CASIO_EXPORT casio_make_posix_path_array OF((casio_path_t **casio__path, const char *casio__rawpath)); @@ -36,8 +49,25 @@ CASIO_EXTERN int CASIO_EXPORT casio_make_posix_path_array /* File information gathering. */ CASIO_EXTERN int CASIO_EXPORT casio_posix_stat - OF((void *casio__cookie, void *casio__path, + OF((void *casio__cookie, posix_path_t casio__path, casio_stat_t *casio__file_info)); +/* Make a file. */ + +# if defined(__STDC__) && __STDC__ +CASIO_EXTERN int CASIO_EXPORT casio_posix_make(void *casio__cookie, + posix_path_t casio__path, const casio_stat_t *casio__info, ...); +# else +CASIO_EXTERN int CASIO_EXPORT casio_posix_make(); +# endif + +CASIO_EXTERN int CASIO_EXPORT casio_posix_makedir + OF((void *casio__cookie, posix_path_t casio__path)); + +/* Delete a file. */ + +CASIO_EXTERN int CASIO_EXPORT casio_posix_delete + OF((void *casio__cookie, posix_path_t casio__path)); + # endif #endif /* LOCAL_FS_BUILTIN_POSIX_H */ diff --git a/src/fs/builtin/posix/stat.c b/src/fs/builtin/posix/stat.c index 25cf603..d05f907 100644 --- a/src/fs/builtin/posix/stat.c +++ b/src/fs/builtin/posix/stat.c @@ -16,6 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with libcasio; if not, see . * ************************************************************************* */ +#define PATH_FTW #include "posix.h" #ifndef LIBCASIO_DISABLED_POSIX_FS diff --git a/src/fs/builtin/posix/topath.c b/src/fs/builtin/posix/topath.c index 788a643..3c83a6e 100644 --- a/src/fs/builtin/posix/topath.c +++ b/src/fs/builtin/posix/topath.c @@ -16,6 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with libcasio; if not, see . * ************************************************************************* */ +#define PATH_FTW #include "posix.h" #ifndef LIBCASIO_DISABLED_POSIX_FS diff --git a/src/fs/makedir.c b/src/fs/makedir.c deleted file mode 100644 index 637ed3d..0000000 --- a/src/fs/makedir.c +++ /dev/null @@ -1,70 +0,0 @@ -/* **************************************************************************** - * fs/makedir.c -- make a directory on a libcasio filesystem. - * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey - * - * This file is part of libcasio. - * libcasio is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3.0 of the License, - * or (at your option) any later version. - * - * libcasio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libcasio; if not, see . - * ************************************************************************* */ -#include "fs.h" - -/** - * casio_makedir: - * Make a directory using a native path. - * - * @arg fs the filesystem. - * @arg path the path of the directory to make. - * @return the error code (0 if ok). - */ - -int CASIO_EXPORT casio_makedir(casio_fs_t *fs, void *path) -{ - casio_fs_makedir_t *makedir; - int err; - - /* Get the callback. */ - makedir = fs->casio_fs_funcs.casio_fsfuncs_makedir; - if (!makedir) return (casio_error_op); - - /* Make the operation. */ - err = (*makedir)(fs->casio_fs_cookie, path); - return (err); -} - -/** - * casio_makedir_path: - * Make a directory using an abstract path. - * - * @arg fs the filesystem. - * @arg path the path of the directory to make. - * @return the error code (0 if ok). - */ - -int CASIO_EXPORT casio_makedir_path(casio_fs_t *fs, casio_path_t *path) -{ - casio_fs_makedir_t *makedir; - int err; void *nat = NULL; - - /* Get the callback. */ - makedir = fs->casio_fs_funcs.casio_fsfuncs_makedir; - if (!makedir) return (casio_error_op); - - /* Get the native path. */ - err = casio_make_native_path(fs, &nat, path); - if (err) return (err); - - /* Make the directory. */ - err = (*makedir)(fs->casio_fs_cookie, nat); - casio_free_native_path(fs, nat); - return (err); -} diff --git a/src/fs/pathnode.c b/src/fs/pathnode.c new file mode 100644 index 0000000..acf6cce --- /dev/null +++ b/src/fs/pathnode.c @@ -0,0 +1,82 @@ +/* **************************************************************************** + * fs/pathnode.c -- manage path nodes. + * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey + * + * This file is part of libcasio. + * libcasio is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3.0 of the License, + * or (at your option) any later version. + * + * libcasio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libcasio; if not, see . + * ************************************************************************* */ +#include "fs.h" + +/** + * casio_make_pathnode: + * Make a path node. + * + * @arg pnode the path node to make. + * @arg size the path node data size. + * @return the error code (0 if ok). + */ + +int CASIO_EXPORT casio_make_pathnode(casio_pathnode_t **pnode, size_t size) +{ + casio_pathnode_t *node; + + /* Allocate the node. */ + *pnode = casio_alloc(offsetof(casio_pathnode_t, + casio_pathnode_name) + size, 1); + node = *pnode; if (!node) return (casio_error_alloc); + + /* Set the static attributes. */ + node->casio_pathnode_next = NULL; + node->casio_pathnode_size = size; + + /* Everything went well! */ + return (0); +} + +/** + * casio_free_pathnode: + * Free a path node. + * + * @arg node the path node to free. + * @return the error code (0 if ok). + */ + +void CASIO_EXPORT casio_free_pathnode(casio_pathnode_t *node) +{ + casio_free(node); +} + +/** + * casio_duplicate_pathnode: + * Duplicate a path node. + * + * @arg new the path node to make. + * @arg old the path node to copy. + * @return the error code (0 if ok). + */ + +int CASIO_EXPORT casio_duplicate_pathnode(casio_pathnode_t **new, + const casio_pathnode_t *old) +{ + int err; size_t sz; + + /* Make the new path node. */ + sz = old->casio_pathnode_size; + err = casio_make_pathnode(new, sz); + if (err) return (err); + + /* Copy the data and return. */ + memcpy((*new)->casio_pathnode_name, old->casio_pathnode_name, sz); + return (0); +}