Tidying up
This commit is contained in:
parent
329640d1ac
commit
31130131c6
|
@ -9,6 +9,9 @@
|
|||
/* ************************************************************************** */
|
||||
#ifndef LIBG1M_H
|
||||
# define LIBG1M_H
|
||||
# include <libg1m/bcd.h>
|
||||
# include <libg1m/fontcharacter.h>
|
||||
# include <libg1m/color.h>
|
||||
# include <stdio.h>
|
||||
# include <stdint.h>
|
||||
# include <time.h>
|
||||
|
@ -46,36 +49,6 @@ extern const char *g1m_error_strings[];
|
|||
# define g1m_strerror(N) g1m_error_strings[N]
|
||||
# define g1m_geterror(N) g1m_error_strings[N]
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Useful types */
|
||||
/* ************************************************************************** */
|
||||
/* BCD number */
|
||||
struct bcd {
|
||||
/* the BCD value */
|
||||
uint8_t BCDval[9];
|
||||
|
||||
/* and some 4-bytes alignment stuff */
|
||||
uint8_t align[3];
|
||||
};
|
||||
|
||||
/* FONTCHARACTER, CASIO's encoding */
|
||||
typedef uint16_t FONTCHARACTER;
|
||||
|
||||
/* color */
|
||||
# define g1m_marker_color(C) (((C) & 0xf0) >> 4)
|
||||
# define g1m_char_color(C) ((C) & 0xf)
|
||||
# define g1m_character_color(C) g1m_char_color(C)
|
||||
typedef enum {
|
||||
g1m_color_black = 0,
|
||||
g1m_color_blue = 1,
|
||||
g1m_color_green = 2,
|
||||
g1m_color_cyan = 3,
|
||||
g1m_color_red = 4,
|
||||
g1m_color_magenta = 5,
|
||||
g1m_color_yellow = 6,
|
||||
g1m_color_white = 7
|
||||
} g1m_color_t;
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* MCS-Related types */
|
||||
/* ************************************************************************** */
|
||||
|
@ -187,17 +160,6 @@ int g1m_parse_mcsfile_content(g1m_mcsfile_t **handle, FILE *stream,
|
|||
void g1m_free(g1m_t *handle);
|
||||
void g1m_free_mcsfile(g1m_mcsfile_t *handle);
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Utilities */
|
||||
/* ************************************************************************** */
|
||||
/* encoding characters */
|
||||
int g1m_mbtofc(FONTCHARACTER *pfc, const char *s, size_t n);
|
||||
int g1m_fctomb(char *s, FONTCHARACTER fc);
|
||||
|
||||
/* encoding strings */
|
||||
size_t g1m_mbstofcs(FONTCHARACTER *dst, const char *src, size_t n);
|
||||
size_t g1m_fcstombs(char *dst, const FONTCHARACTER *src, size_t n);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* ************************************************************************** */
|
||||
/* _____ _ */
|
||||
/* libg1m/bcd.h |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/21 09:23:44 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#ifndef LIBG1M_BCD_H
|
||||
# define LIBG1M_BCD_H
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Type definition */
|
||||
/* ************************************************************************** */
|
||||
/* BCD are the main number format CASIO uses in its calculators.
|
||||
* Each semi-byte is a digit going from 0 to 9 (0xA to 0xF aren't used).
|
||||
* This format has the huge advantage to make 0.1 + 0.2 and 0.3 equal.
|
||||
*
|
||||
* The first three digits are the exponent.
|
||||
* If the exponent is more than 500, then remove 500, and that means the
|
||||
* number is negative.
|
||||
* Then you have to remove 100 to have the real exponent.
|
||||
*
|
||||
* The other 15 digits are the mantissa. So the number is: (0,M ** E) */
|
||||
|
||||
struct bcd {
|
||||
/* the BCD value itself */
|
||||
unsigned char BCDval[9];
|
||||
|
||||
/* some 4-bytes alignment stuff */
|
||||
unsigned char _align[3];
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* BCD utilities */
|
||||
/* ************************************************************************** */
|
||||
/* none yet -- TODO */
|
||||
|
||||
#endif /* LIBG1M_BCD_H */
|
|
@ -0,0 +1,38 @@
|
|||
/* ************************************************************************** */
|
||||
/* _____ _ */
|
||||
/* libg1m/color.h |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/21 09:32:56 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#ifndef LIBG1M_COLOR_H
|
||||
# define LIBG1M_COLOR_H
|
||||
|
||||
/* This header is about colors in e-activities for fx-CG calculators.
|
||||
*
|
||||
* For each text line, there can be a "color zone" that has the same size as
|
||||
* the content. Each byte is organized as 0xMC, where 'M' is the marker color
|
||||
* (background color) whereas 'C' is the character color.
|
||||
*
|
||||
* These colors are the following: */
|
||||
|
||||
typedef enum {
|
||||
g1m_color_black = 0,
|
||||
g1m_color_blue = 1,
|
||||
g1m_color_green = 2,
|
||||
g1m_color_cyan = 3,
|
||||
g1m_color_red = 4,
|
||||
g1m_color_magenta = 5,
|
||||
g1m_color_yellow = 6,
|
||||
g1m_color_white = 7
|
||||
} g1m_color_t;
|
||||
|
||||
/* And here are some macros to help you out: */
|
||||
|
||||
# define g1m_marker_color(C) (((C) & 0xf0) >> 4)
|
||||
# define g1m_char_color(C) ((C) & 0xf)
|
||||
# define g1m_character_color(C) g1m_char_color(C)
|
||||
|
||||
#endif /* LIBG1M_COLOR_H */
|
|
@ -0,0 +1,36 @@
|
|||
/* ************************************************************************** */
|
||||
/* _____ _ */
|
||||
/* libg1m/fontcharacter.h |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/21 09:26:47 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#ifndef LIBG1M_FONTCHARACTER_H
|
||||
# define LIBG1M_FONTCHARACTER_H
|
||||
# include <stdlib.h>
|
||||
# include <stdint.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Main type */
|
||||
/* ************************************************************************** */
|
||||
/* CASIO's character encoding, named `FONTCHARACTER` by its SDK, is a simple
|
||||
* multibyte one : if the character is a special one, then the next one is
|
||||
* to read.
|
||||
*
|
||||
* Special characters are: 0x7F, 0xF7, 0xF9, 0xE5, 0xE6, 0xE7. */
|
||||
typedef uint16_t FONTCHARACTER;
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Utilities */
|
||||
/* ************************************************************************** */
|
||||
/* encoding characters */
|
||||
int g1m_mbtofc(FONTCHARACTER *pfc, const char *s, size_t n);
|
||||
int g1m_fctomb(char *s, FONTCHARACTER fc);
|
||||
|
||||
/* encoding strings */
|
||||
size_t g1m_mbstofcs(FONTCHARACTER *dst, const char *src, size_t n);
|
||||
size_t g1m_fcstombs(char *dst, const FONTCHARACTER *src, size_t n);
|
||||
|
||||
#endif /* LIBG1M_FONTCHARACTER_H */
|
|
@ -0,0 +1,92 @@
|
|||
/* ************************************************************************** */
|
||||
/* _____ _ */
|
||||
/* user/free.c |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/21 09:13:10 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* g1m_free_mcsfile:
|
||||
* Free an MCS file handle.
|
||||
*
|
||||
* @arg handle the handle to free.
|
||||
*/
|
||||
|
||||
void g1m_free_mcsfile(g1m_mcsfile_t *handle)
|
||||
{
|
||||
/* free cells */
|
||||
if (handle->type & (g1m_mcstype_mat | g1m_mcstype_list
|
||||
| g1m_mcstype_spreadsheet)
|
||||
&& handle->columns && handle->rows) {
|
||||
free(handle->cells[0]);
|
||||
free(handle->cells);
|
||||
}
|
||||
|
||||
/* free the images */
|
||||
if (handle->type & (g1m_mcstype_pict | g1m_mcstype_capt)) {
|
||||
free(handle->image);
|
||||
if (handle->type & g1m_mcstype_capt)
|
||||
free(handle->second_image);
|
||||
}
|
||||
|
||||
/* free the handle */
|
||||
free(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_free_mcs:
|
||||
* Free all of the MCS.
|
||||
*
|
||||
* @arg handle the handle to close.
|
||||
*/
|
||||
|
||||
void g1m_free_mcs(g1m_t *handle)
|
||||
{
|
||||
/* check if mcs */
|
||||
if (!handle->parts)
|
||||
return ;
|
||||
|
||||
/* foreach mcs */
|
||||
g1m_mcs_t **mcs = handle->parts;
|
||||
int mcs_count = handle->part_count;
|
||||
for (int i = 0; i < mcs_count; i++) {
|
||||
/* check if used */
|
||||
if (!mcs[i])
|
||||
continue ;
|
||||
|
||||
/* foreach file in mcs */
|
||||
g1m_mcsfile_t **files = mcs[i]->files;
|
||||
int file_count = mcs[i]->file_count;
|
||||
for (int j = 0; j < file_count; j++)
|
||||
/* free the file if exists */
|
||||
if (files[j]) g1m_free_mcsfile(files[j]);
|
||||
free(files);
|
||||
free(mcs[i]);
|
||||
}
|
||||
free(mcs);
|
||||
handle->parts = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_free:
|
||||
* Free handle data.
|
||||
*
|
||||
* @arg handle the handle to close.
|
||||
*/
|
||||
|
||||
void g1m_free(g1m_t *handle)
|
||||
{
|
||||
if (!handle) return ;
|
||||
|
||||
/* mcs time! */
|
||||
if (handle->type & g1m_type_mcs && handle->parts)
|
||||
g1m_free_mcs(handle);
|
||||
|
||||
/* free the handle */
|
||||
free(handle);
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* _____ _ */
|
||||
/* handle.c |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/10/31 00:14:27 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Open operations (parsing has its own module) */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_open:
|
||||
* Open handle using path.
|
||||
*
|
||||
* @arg handle the handle to create.
|
||||
* @arg path the path of the file to open.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_open(g1m_t **handle, const char *path)
|
||||
{
|
||||
/* open stream */
|
||||
FILE *f = fopen(path, "r");
|
||||
|
||||
/* open using `g1m_fopen` */
|
||||
int err = g1m_fopen(handle, f);
|
||||
|
||||
/* close opened stream and return error code (or 0 if ok) */
|
||||
if (f) fclose(f);
|
||||
return (err);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_fopen:
|
||||
* Open handle using FILE* pointer.
|
||||
*
|
||||
* Will not seek, and will not keep the stream.
|
||||
* Make sure to fclose the stream after use.
|
||||
*
|
||||
* @arg handle the handle to create
|
||||
* @arg stream the stream
|
||||
* @return the error code (0 if ok)
|
||||
*/
|
||||
|
||||
int g1m_fopen(g1m_t **handle, FILE *stream)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* check stream */
|
||||
if (!stream) return (g1m_error_nostream);
|
||||
if (!__freadable(stream)) return (g1m_error_noread);
|
||||
|
||||
/* create the handle */
|
||||
*handle = malloc(sizeof(g1m_t));
|
||||
if (!*handle) return (g1m_error_alloc);
|
||||
|
||||
/* fill it by parsing opened file */
|
||||
if ((err = g1m_parse(*handle, stream))) {
|
||||
free(*handle);
|
||||
*handle = NULL;
|
||||
return (err);
|
||||
}
|
||||
|
||||
/* everything ok */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Free the data */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_free_mcsfile:
|
||||
* Free an MCS file handle.
|
||||
*
|
||||
* @arg handle the handle to free.
|
||||
*/
|
||||
|
||||
void g1m_free_mcsfile(g1m_mcsfile_t *handle)
|
||||
{
|
||||
/* free cells */
|
||||
if (handle->type & (g1m_mcstype_mat | g1m_mcstype_list
|
||||
| g1m_mcstype_spreadsheet)
|
||||
&& handle->columns && handle->rows) {
|
||||
free(handle->cells[0]);
|
||||
free(handle->cells);
|
||||
}
|
||||
|
||||
/* free the first image */
|
||||
if (handle->type & (g1m_mcstype_pict | g1m_mcstype_capt))
|
||||
free(handle->image);
|
||||
|
||||
/* free the second image */
|
||||
if (handle->type & g1m_mcstype_pict)
|
||||
free(handle->second_image);
|
||||
|
||||
/* free the handle */
|
||||
free(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_free_mcs:
|
||||
* Free all of the MCS.
|
||||
*
|
||||
* @arg handle the handle to close.
|
||||
*/
|
||||
|
||||
void g1m_free_mcs(g1m_t *handle)
|
||||
{
|
||||
/* check if mcs */
|
||||
if (!handle->parts)
|
||||
return ;
|
||||
|
||||
/* foreach mcs */
|
||||
g1m_mcs_t **mcs = handle->parts;
|
||||
int mcs_count = handle->part_count;
|
||||
for (int i = 0; i < mcs_count; i++) {
|
||||
/* check if used */
|
||||
if (!mcs[i])
|
||||
continue ;
|
||||
|
||||
/* foreach file in mcs */
|
||||
g1m_mcsfile_t **files = mcs[i]->files;
|
||||
int file_count = mcs[i]->file_count;
|
||||
for (int j = 0; j < file_count; j++) {
|
||||
/* check if mcs */
|
||||
if (!files[j])
|
||||
continue ;
|
||||
|
||||
/* free the file */
|
||||
g1m_free_mcsfile(files[j]);
|
||||
}
|
||||
free(files);
|
||||
free(mcs[i]);
|
||||
}
|
||||
free(mcs);
|
||||
handle->parts = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_free:
|
||||
* Free handle data.
|
||||
*
|
||||
* @arg handle the handle to close.
|
||||
*/
|
||||
|
||||
void g1m_free(g1m_t *handle)
|
||||
{
|
||||
if (!handle) return ;
|
||||
|
||||
/* mcs time! */
|
||||
if (handle->type & g1m_type_mcs && handle->parts)
|
||||
g1m_free_mcs(handle);
|
||||
|
||||
/* free the handle */
|
||||
free(handle);
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/* ************************************************************************** */
|
||||
/* _____ _ */
|
||||
/* user/open.c |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/21 09:14:15 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* g1m_open:
|
||||
* Open handle using path.
|
||||
*
|
||||
* @arg handle the handle to create.
|
||||
* @arg path the path of the file to open.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_open(g1m_t **handle, const char *path)
|
||||
{
|
||||
/* open stream */
|
||||
FILE *f = fopen(path, "r");
|
||||
|
||||
/* open using `g1m_fopen` */
|
||||
int err = g1m_fopen(handle, f);
|
||||
|
||||
/* close opened stream and return error code (or 0 if ok) */
|
||||
if (f) fclose(f);
|
||||
return (err);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_fopen:
|
||||
* Open handle using FILE* pointer.
|
||||
*
|
||||
* Will not seek, and will not keep the stream.
|
||||
* Make sure to fclose the stream after use.
|
||||
*
|
||||
* @arg handle the handle to create
|
||||
* @arg stream the stream
|
||||
* @return the error code (0 if ok)
|
||||
*/
|
||||
|
||||
int g1m_fopen(g1m_t **handle, FILE *stream)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* check stream */
|
||||
if (!stream) return (g1m_error_nostream);
|
||||
if (!__freadable(stream)) return (g1m_error_noread);
|
||||
|
||||
/* create the handle */
|
||||
*handle = malloc(sizeof(g1m_t));
|
||||
if (!*handle) return (g1m_error_alloc);
|
||||
|
||||
/* fill it by parsing opened file */
|
||||
if ((err = g1m_parse(*handle, stream))) {
|
||||
free(*handle);
|
||||
*handle = NULL;
|
||||
return (err);
|
||||
}
|
||||
|
||||
/* everything ok */
|
||||
return (0);
|
||||
}
|
Reference in New Issue