cake
/
libg1m
Archived
1
0
Fork 0

Tidying up

This commit is contained in:
Thomas Touhey 2016-11-21 10:26:52 +01:00
parent 329640d1ac
commit 31130131c6
7 changed files with 278 additions and 203 deletions

View File

@ -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

40
include/libg1m/bcd.h Normal file
View File

@ -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 */

38
include/libg1m/color.h Normal file
View File

@ -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 */

View File

@ -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 */

92
src/user/free.c Normal file
View File

@ -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);
}

View File

@ -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);
}

69
src/user/open.c Normal file
View File

@ -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);
}