cake
/
libg1m
Archived
1
0
Fork 0

Tried to implement CAS file groups.

This commit is contained in:
Thomas Touhey 2017-03-08 21:43:53 +01:00
parent dfca7ea255
commit 795c9638c6
10 changed files with 376 additions and 237 deletions

View File

@ -19,8 +19,9 @@
* WARNING: Do NOT include this header using <libg1m-(version)/libg1m.h>!
*
* Compile using one of these:
* libg1m-config --cflags
* pkg-config libg1m --cflags
*
* libg1m-config --cflags
* pkg-config libg1m --cflags
*
* and include using <libg1m.h>.
* ************************************************************************** */
@ -73,9 +74,10 @@ extern const char *g1m_error_strings[];
/* ************************************************************************** */
/* Main functions */
/* ************************************************************************** */
/* open a handle */
/* open and free a handle */
int g1m_decode(g1m_t *handle, const char *path, g1m_buffer_t *buffer,
g1m_type_t expected_type);
void g1m_free(g1m_t *handle);
/* open a handle using FILEs */
#ifndef G1M_DISABLED_FILE
@ -85,8 +87,13 @@ int g1m_fopen(g1m_t **handle, const char *path, FILE *stream,
g1m_type_t expected_type);
#endif
/* ************************************************************************** */
/* Main MCS functions */
/* ************************************************************************** */
/* make an MCS file out of a head */
int g1m_make_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *rawhead);
int g1m_prepare_mcsfile_heads(g1m_mcshead_t *head, g1m_mcshead_t *heads);
void g1m_free_mcsfile(g1m_mcsfile_t *handle);
/* open MCS head for decoding, correct it for encoding */
int g1m_decode_mcsfile_head(g1m_mcshead_t *head,
@ -103,19 +110,18 @@ int g1m_decode_mcsfile_data(g1m_mcsfile_t **handle,
/* open CAS head for decoding
* --------------------------
* if the head corresponds to something you want as a file (e.g. g1m_mcstype_end
* then you should make the file using `g1m_make_mcsfile`, and call
* `g1m_decode_casfile_part` while the `g1m_mcsflag_unfinished` flag is set.
* if the head corresponds to something you want as a file (e.g.
* not `g1m_mcstype_end`), then you should make the file using
* `g1m_make_mcsfile`, and call `g1m_decode_casfile_part` while the
* `g1m_mcsflag_unfinished` flag is set.
* Warning: there could be no parts to read! (e.g. unset variable) */
int g1m_decode_casfile_head(g1m_mcshead_t *head, g1m_buffer_t *buffer);
int g1m_decode_casfiles_part(g1m_mcshead_t *head, g1m_mcshead_t *heads,
g1m_buffer_t *buffer);
int g1m_decode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer);
/* free handles */
void g1m_free(g1m_t *handle);
void g1m_free_mcsfile(g1m_mcsfile_t *handle);
/* ************************************************************************** */
/* MCS file manipulation */
/* MCS archive management */
/* ************************************************************************** */
/* add MCS files */
int g1m_putmcs_program(g1m_t *handle, g1m_mcsfile_t **pfile,

View File

@ -146,9 +146,13 @@ G1M_MCSFUNC(string)
/* ************************************************************************** */
# define G1M_CASFUNC(NAME) \
int g1m_decode_caspart_##NAME(g1m_mcsfile_t *handle, g1m_buffer_t *buffer);
# define G1M_CASHFUNC(NAME) \
int g1m_decode_cashpart_##NAME(g1m_mcshead_t *head, g1m_mcshead_t *heads, \
g1m_buffer_t *buffer);
G1M_CASFUNC(var)
G1M_CASFUNC(program)
G1M_CASHFUNC(program)
/* ************************************************************************** */
/* Picture utilities */
/* ************************************************************************** */
@ -171,7 +175,6 @@ G1M_CASFUNC(program)
G1M_PROTOTYPE_PIX(packed1bit)
G1M_PROTOTYPE_PIX(packed4bits)
G1M_PROTOTYPE_PIX(16bits)
/* ************************************************************************** */
/* Utilities */
/* ************************************************************************** */
@ -180,7 +183,6 @@ int g1m_make_mcs(g1m_t **h);
/* Free-ing */
void g1m_free_content(g1m_t *handle);
void g1m_free_mcsfile_content(g1m_mcsfile_t *handle);
void g1m_free_mcs(g1m_t *handle);
void g1m_free_line_content(g1m_line_t *line);

View File

@ -81,16 +81,17 @@ typedef struct g1m_mcs_cell_s {
/* ************************************************************************** */
/* mcs file head flags */
# define g1m_mcsflag_unfinished 0x8000 /* is there still parts to read? */
# define g1m_mcsflag_multiple 0x4000 /* is a group */
# define g1m_mcsflag_complex 0x0001 /* is a complex variable */
/* mcs file type -- what type of raw information is there
* e.g. `head.flags & g1m_mcsmask_info == g1m_mcsinfo_g1m` */
# define g1m_mcsinfo(H) ((H)->flags & g1m_mcsmask_info)
# define g1m_mcsmask_info 0x6000
# define g1m_mcsmask_info 0x0600
# define g1m_mcsinfo_none 0x0000
# define g1m_mcsinfo_mcs 0x2000
# define g1m_mcsinfo_cas 0x4000
# define g1m_mcsinfo_caspro 0x6000
# define g1m_mcsinfo_mcs 0x0200
# define g1m_mcsinfo_cas 0x0400
# define g1m_mcsinfo_caspro 0x0600
/* mcs file head */
typedef struct g1m_mcshead_s {

View File

@ -41,60 +41,6 @@ void g1m_free_line_content(g1m_line_t *line)
}
}
/**
* g1m_free_mcsfile_content:
* Free an MCS file handle content.
*
* @arg handle the handle which has the content to free.
*/
void g1m_free_mcsfile_content(g1m_mcsfile_t *handle)
{
unsigned int type = handle->head.type;
/* free content for unknown files */
if (!type)
free(handle->content);
/* free cells */
if (type & (g1m_mcstype_mat | g1m_mcstype_vct | g1m_mcstype_list
| g1m_mcstype_spreadsheet)
&& handle->head.width && handle->head.height) {
free(handle->cells[0]);
free(handle->cells);
}
/* free the images */
if ((type & (g1m_mcstype_pict | g1m_mcstype_capt))) {
for (int i = 0; i < handle->head.count; i++)
free(handle->pics[i]);
if (handle->pics != &handle->pic)
free(handle->pics);
}
/* free the vars */
if ((type & g1m_mcstype_alphamem)
&& handle->vars != &handle->var)
free(handle->vars);
/* free the content */
if (type & (g1m_mcstype_program | g1m_mcstype_setup))
free(handle->content);
}
/**
* g1m_free_mcsfile:
* Free an MCS file handle.
*
* @arg handle the handle to free.
*/
void g1m_free_mcsfile(g1m_mcsfile_t *handle)
{
g1m_free_mcsfile_content(handle);
free(handle);
}
/**
* g1m_free_mcs:
* Free all of the MCS.

View File

@ -21,24 +21,32 @@
* ************************************************************************** */
#include <libg1m/internals.h>
#define FUNC(NAME) g1m_decode_caspart_##NAME
#define HFUNC(NAME) g1m_decode_cashpart_##NAME
#define READCOLON() { \
uint8_t colon; GREAD(&colon, 1) \
err = g1m_error_magic; \
if (colon != ':') goto fail; }
/* ************************************************************************** */
/* Type correspondance list */
/* ************************************************************************** */
/* Part parsing function type */
typedef int (*cas_decode_function)(g1m_mcsfile_t*, g1m_buffer_t*);
typedef int (*cas_heads_decode_function)(g1m_mcshead_t *head,
g1m_mcshead_t *heads, g1m_buffer_t *buffer);
/* Correspondance type */
struct cas_corresp {
unsigned int type;
cas_decode_function decode;
cas_heads_decode_function hdecode;
};
/* All correspondances */
#define TTERM {0, NULL}
#define TTERM {0, NULL, NULL}
static struct cas_corresp cas_types[] = {
{g1m_mcstype_var, FUNC(var)},
{g1m_mcstype_program, FUNC(program)},
{g1m_mcstype_var, FUNC(var), NULL},
{g1m_mcstype_program, FUNC(program), HFUNC(program)},
TTERM
};
@ -50,7 +58,7 @@ static struct cas_corresp cas_types[] = {
* @return the function (NULL if not found).
*/
static cas_decode_function lookup_cas_decode(g1m_mcstype_t type)
static void *lookup_cas_decode(g1m_mcstype_t type, int heads)
{
/* lookup for the type */
struct cas_corresp *c = cas_types;
@ -61,7 +69,7 @@ static cas_decode_function lookup_cas_decode(g1m_mcstype_t type)
}
/* return the function */
return (c->decode);
return (heads ? (void*)c->hdecode : (void*)c->decode);
}
/* ************************************************************************** */
@ -126,6 +134,7 @@ int g1m_decode_casfile_head(g1m_mcshead_t *head, g1m_buffer_t *buffer)
{
/* check that the head exists */
if (!head) return (-1);
memset(head, 0, sizeof(g1m_mcshead_t));
/* read beginning of the header, try to guess a newer header */
uint8_t buf[49]; READ(buf, 7)
@ -160,6 +169,30 @@ int g1m_decode_casfile_head(g1m_mcshead_t *head, g1m_buffer_t *buffer)
/* ************************************************************************** */
/* Part decoding functions */
/* ************************************************************************** */
/**
* g1m_decode_casfiles_part:
* Decode the CASIOLINK group parts.
*
* @arg head the general head.
* @arg heads the heads to contribute to.
* @arg buffer the buffer to read from.
* @return the error that occurred (0 if ok).
*/
int g1m_decode_casfiles_part(g1m_mcshead_t *head, g1m_mcshead_t *heads,
g1m_buffer_t *buffer)
{
/* look for the decoding function */
cas_heads_decode_function decode = (void*)lookup_cas_decode(head->type, 1);
if (!decode) {
log_error("No dedicated decoding function was found for this type!");
return (g1m_error_unknown);
}
/* decode the part */
return ((*decode)(head, heads, buffer));
}
/**
* g1m_decode_casfile_part:
* Decode a CASIOLINK Protocol content part.
@ -175,7 +208,7 @@ int g1m_decode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer)
if (!file) return (g1m_error_op);
/* look for the decoding function */
cas_decode_function decode = lookup_cas_decode(file->head.type);
cas_decode_function decode = (void*)lookup_cas_decode(file->head.type, 0);
if (!decode) {
log_error("No dedicated decoding function was found for this type!");
return (g1m_error_unknown);
@ -192,7 +225,8 @@ int g1m_decode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer)
* g1m_decode_cas:
* Decode a CAS file. TODO.
*
* The colon ':' (0x3A) is already read at this point.
* Is also sort of a guide for using the CAS MCS files.
* The colon ':' (0x3A) is already read at this point (CAS file id.).
*
* @arg handle the handle to create.
* @arg buffer the buffer to read from.
@ -213,14 +247,32 @@ int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer,
/* read each */
for (handle->count = 0;;) {
/* read the head */
log_info("Reading file head #%d", handle->count);
g1m_mcshead_t head;
log_info("Reading the next head.");
g1m_mcshead_t head = {};
if ((err = g1m_decode_casfile_head(&head, buffer))) goto fail;
if (head.type == g1m_mcstype_end) break;
/* heads up! */
int numheads = head.flags & g1m_mcsflag_multiple ? head.count : 1;
g1m_mcshead_t heads[numheads];
if (head.flags & g1m_mcsflag_multiple) {
log_info("Is a head for multiple files!");
g1m_prepare_mcsfile_heads(&head, heads);
while (head.flags & g1m_mcsflag_unfinished) {
READCOLON()
/* decode a general part */
err = g1m_decode_casfiles_part(&head, heads, buffer);
if (err) goto fail;
}
} else
heads[0] = head;
/* prepare space in the index */
if (handle->count == handle->_size) {
int newsize = handle->_size + 4;
int required_size = handle->count
+ (head.flags & g1m_mcsflag_multiple) ? head.count : 1;
if (required_size > handle->_size) {
int newsize = required_size + 2;
log_info("index not big enough, allocating from %d to %d slots",
handle->_size, newsize);
@ -238,33 +290,31 @@ int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer,
handle->_size = newsize;
}
/* prepare the file */
log_info("Preparing the file.");
err = g1m_make_mcsfile(&handle->files[handle->count], &head);
if (err) goto fail;
/* read each part */
g1m_mcsfile_t *file = handle->files[handle->count]; handle->count++;
#if LOGLEVEL <= ll_info
for (int j = 1; file->head.flags & g1m_mcsflag_unfinished; j++) {
#else
while (file->head.flags & g1m_mcsflag_unfinished) {
#endif
log_info("Reading part #%d", j);
/* read the colon */
uint8_t colon; GREAD(&colon, 1)
err = g1m_error_magic;
if (colon != ':') goto fail;
/* read the part */
err = g1m_decode_casfile_part(file, buffer);
for (int i = 0; i < numheads; i++) {
/* prepare the file */
log_info("Preparing the group file #%d", i);
err = g1m_make_mcsfile(&handle->files[handle->count], &heads[i]);
if (err) goto fail;
g1m_mcsfile_t *file = handle->files[handle->count]; handle->count++;
/* read each part */
#if LOGLEVEL <= ll_info
for (int j = 1; file->head.flags & g1m_mcsflag_unfinished; j++) {
#else
while (file->head.flags & g1m_mcsflag_unfinished) {
#endif
/* initialize */
log_info("Reading part #%d", j);
READCOLON()
/* read the part */
err = g1m_decode_casfile_part(file, buffer);
if (err) goto fail;
}
}
/* read first colon of the next part */
err = g1m_error_magic;
uint8_t nextcolon; GREAD(&nextcolon, 1)
if (nextcolon != ':') goto fail;
READCOLON()
}
/* everything went well :) */

View File

@ -80,11 +80,18 @@ int g1m_decode_mcs_matrix(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
for (uint_fast32_t y = 0; y < h; y++)
for (uint_fast32_t x = 0; x < w; x++) {
g1m_bcdtoa(&tab[y][x].real, rbuf, G1M_BCD_GOODBUFSIZE);
if (g1m_bcd_has_special(&tab[y][x].real)) {
g1m_bcdtoa(&tab[y][x].imgn, ibuf, G1M_BCD_GOODBUFSIZE);
log_info("[%" PRIuFAST32 "] %si + %s", y, ibuf, rbuf);
g1m_bcd_t ibcd = tab[y][x].imgn;
int ch = g1m_bcd_is_negative(&ibcd) ? '-' : '+';
ibcd.flags &= ~g1m_bcdflag_neg;
g1m_bcdtoa(&ibcd, ibuf, G1M_BCD_GOODBUFSIZE);
log_info("[%" PRIuFAST32 "][%" PRIuFAST32 "] %s %c %si",
y, x, rbuf, ch, ibuf);
} else
log_info("[%" PRIuFAST32 "] %s", y, rbuf);
log_info("[%" PRIuFAST32 "][%" PRIuFAST32 "] %s",
y, x, rbuf);
}
#endif

View File

@ -59,6 +59,41 @@ fail:
return (err);
}
/**
* g1m_decode_cashpart_program:
* Decode a CAS heads program part.
*
* @arg head the general head.
* @arg heads the heads to contribute to.
* @arg buffer the buffer to read from.
* @return the error code (0 if ok).
*/
int g1m_decode_cashpart_program(g1m_mcshead_t *head, g1m_mcshead_t *heads,
g1m_buffer_t *buffer)
{
/* get content */
struct cas_spe_program headers[head->count];
READ(headers, sizeof(struct cas_spe_program) * head->count)
/* check the sum */
uint8_t checksum; READ(&checksum, 1)
uint8_t csum = ~g1m_checksum8(headers,
sizeof(struct cas_spe_program) * head->count) + 1;
if (csum != checksum)
return (g1m_error_checksum);
/* initialize */
for (int i = 0; i < head->count; i++) {
heads[i].size = be16toh(headers[i].length);
/* program type? */
}
/* everything went well :D */
head->flags &= ~g1m_mcsflag_unfinished;
return (0);
}
/**
* g1m_decode_caspart_program:
* Decode a CAS program part.

View File

@ -19,108 +19,6 @@
#include <libg1m/internals.h>
#define MCS_CHUNK_SIZE 16
/* ************************************************************************** */
/* Allocate files and content */
/* ************************************************************************** */
/**
* g1m_make_mcsfile:
* Make an MCS file out of a head.
*
* Will allocate all of the required parts of the MCS file for it to be
* filled later.
*
* @arg handle the file to allocate.
* @arg rawhead the head to use.
* @return the error (if any).
*/
int g1m_make_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *rawhead)
{
/* allocate the handle */
*handle = malloc(sizeof(g1m_mcsfile_t));
if (!handle) return (g1m_error_alloc);
g1m_mcsfile_t *h = *handle;
memset(h, 0, sizeof(g1m_mcsfile_t));
/* copy the head */
memcpy(&h->head, rawhead, sizeof(g1m_mcshead_t));
g1m_mcshead_t *head = &h->head;
/* act differently according to the context */
switch (head->type) {
case g1m_mcstype_list: case g1m_mcstype_mat: case g1m_mcstype_vct:
case g1m_mcstype_ssheet:
log_info("Preparing %d*%d matrix", head->width, head->height);
unsigned int wd = head->width, ht = head->height;
if (wd && ht) {
h->cells = malloc(sizeof(g1m_mcs_cell_t*) * ht);
if (!h->cells) goto fail;
h->cells[0] = malloc(sizeof(g1m_mcs_cell_t) * wd * ht);
if (!h->cells[0]) { free(h->cells); goto fail; }
for (unsigned int y = 1; y < ht; y++)
h->cells[y] = &h->cells[0][h->head.width * y];
}
break;
case g1m_mcstype_var:
if (head->count <= 1) h->vars = &h->var;
else {
h->vars = malloc(sizeof(g1m_mcs_cell_t) * head->count);
if (!h->vars) goto fail;
memset(h->vars, 0, sizeof(g1m_mcs_cell_t) * head->count);
}
break;
case g1m_mcstype_pict: case g1m_mcstype_capt:
/* set count */
head->count = (head->type == g1m_mcstype_pict) ? 2 : 1;
/* allocate directory */
if (head->count <= 1) h->pics = &h->pic;
else {
h->pics = malloc(sizeof(uint32_t**) * head->count);
if (!h->pics) goto fail;
}
/* allocate */
for (int i = 0; i < head->count; i++) {
h->pics[i] = alloc_pixels(head->width, head->height);
if (!h->pics[i]) {
for (int j = 0; j < i; j++)
free(h->pics[j]);
if (h->pics != &h->pic)
free(h->pics);
goto fail;
}
}
/* prepare */
for (int i = 0; i < head->count; i++)
prepare_pixels(h->pics[i], head->width, head->height)
break;
case g1m_mcstype_end:
break;
/* those are TEMPORARY XXX */
case g1m_mcstype_string:
break;
default:
h->content = malloc(head->size);
if (!h->content) goto fail;
break;
}
/* finish */
return (0);
fail:
free(h);
*handle = NULL;
return (g1m_error_alloc);
}
/* ************************************************************************** */
/* Internal functions */
/* ************************************************************************** */

190
src/manage/mcsfile.c Normal file
View File

@ -0,0 +1,190 @@
/* *****************************************************************************
* manage/mcsfile.c -- manage an MCS file.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libg1m.
* libg1m 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.
*
* libg1m 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 libg1m; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************** */
#include <libg1m/internals.h>
/**
* g1m_make_mcsfile:
* Make an MCS file out of a head.
*
* Will allocate all of the required parts of the MCS file for it to be
* filled later.
*
* @arg handle the file to allocate.
* @arg rawhead the head to use.
* @return the error (if any).
*/
int g1m_make_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *rawhead)
{
/* allocate the handle */
*handle = malloc(sizeof(g1m_mcsfile_t));
if (!handle) return (g1m_error_alloc);
g1m_mcsfile_t *h = *handle;
memset(h, 0, sizeof(g1m_mcsfile_t));
/* copy the head */
memcpy(&h->head, rawhead, sizeof(g1m_mcshead_t));
g1m_mcshead_t *head = &h->head;
switch (head->type) {
/* allocate the cells */
case g1m_mcstype_list: case g1m_mcstype_mat: case g1m_mcstype_vct:
case g1m_mcstype_ssheet:
log_info("Preparing %d*%d matrix", head->width, head->height);
unsigned int wd = head->width, ht = head->height;
if (wd && ht) {
h->cells = malloc(sizeof(g1m_mcs_cell_t*) * ht);
if (!h->cells) goto fail;
h->cells[0] = malloc(sizeof(g1m_mcs_cell_t) * wd * ht);
if (!h->cells[0]) { free(h->cells); goto fail; }
for (unsigned int y = 1; y < ht; y++)
h->cells[y] = &h->cells[0][h->head.width * y];
}
break;
/* allocate the variables */
case g1m_mcstype_alphamem:
if (head->count <= 1) h->vars = &h->var;
else {
h->vars = malloc(sizeof(g1m_mcs_cell_t) * head->count);
if (!h->vars) goto fail;
memset(h->vars, 0, sizeof(g1m_mcs_cell_t) * head->count);
}
break;
/* allocate the set of pixels */
case g1m_mcstype_pict: case g1m_mcstype_capt:
/* set count */
head->count = (head->type == g1m_mcstype_pict) ? 2 : 1;
/* allocate directory */
if (head->count <= 1) h->pics = &h->pic;
else {
h->pics = malloc(sizeof(uint32_t**) * head->count);
if (!h->pics) goto fail;
}
/* allocate */
for (int i = 0; i < head->count; i++) {
h->pics[i] = alloc_pixels(head->width, head->height);
if (!h->pics[i]) {
for (int j = 0; j < i; j++)
free(h->pics[j]);
if (h->pics != &h->pic)
free(h->pics);
goto fail;
}
}
/* prepare */
for (int i = 0; i < head->count; i++)
prepare_pixels(h->pics[i], head->width, head->height)
break;
/* allocate nothing */
case g1m_mcstype_end:
case g1m_mcstype_string: /* TEMPORARY XXX */
break;
/* allocate raw content */
default:
h->content = malloc(head->size);
if (!h->content) goto fail;
break;
}
/* finish */
return (0);
fail:
free(h);
*handle = NULL;
return (g1m_error_alloc);
}
/**
* g1m_prepare_mcsfile_heads:
* Prepare the heads from a general head.
*
* @arg head the main head.
* @arg heads the heads to prepare.
* @return the error (if any).
*/
int g1m_prepare_mcsfile_heads(g1m_mcshead_t *head, g1m_mcshead_t *heads)
{
/* check if the head is a multiple head */
if (~head->flags & g1m_mcsflag_multiple) return (g1m_error_op);
/* copy the data in each head */
for (int i = 0; i < head->count; i++) {
heads[i] = *head;
heads[i].flags &= ~g1m_mcsflag_multiple;
}
/* no error */
return (0);
}
/**
* g1m_free_mcsfile:
* Free an MCS file handle content.
*
* @arg handle the handle which has the content to free.
*/
void g1m_free_mcsfile(g1m_mcsfile_t *handle)
{
switch (handle->head.type) {
/* free the cells */
case g1m_mcstype_mat: case g1m_mcstype_vct: case g1m_mcstype_list:
case g1m_mcstype_ssheet:
if (handle->head.width && handle->head.height) {
free(handle->cells[0]);
free(handle->cells);
}
break;
/* free the set of pixels */
case g1m_mcstype_pict: case g1m_mcstype_capt:
for (int i = 0; i < handle->head.count; i++)
free(handle->pics[i]);
if (handle->pics != &handle->pic)
free(handle->pics);
break;
/* free the variables */
case g1m_mcstype_alphamem:
if (handle->vars != &handle->var)
free(handle->vars);
break;
/* free nothing */
case g1m_mcstype_end:
case g1m_mcstype_string: /* TEMPORARY XXX */
break;
/* free the raw content */
default:
free(handle->content);
}
/* free the content */
free(handle);
}

View File

@ -26,43 +26,46 @@ struct type_corresp {
/* identification */
const char *datatype;
/* libg1m MCS file type */
/* libg1m MCS file type, flags */
g1m_mcstype_t type;
unsigned int flags;
};
/* ************************************************************************** */
/* Correspondances */
/* ************************************************************************** */
/* All correspondances. Remarks:
/* All correspondances found by Tom Wheeley and Tom Lynn. Remarks:
* - Correspondances with a NULL data type means the data type isn't to be
* read. */
#define TTERM {NULL, 0}
#define TTERM {NULL, 0, 0}
static struct type_corresp cas_groups[] = {
/* not implemented yet types, described by Tom Wheeley and Tom Lynn */
{"AA", 0}, // dynamic graph functions
{"AD", 0}, // variable memory
{"AL", 0}, // all
{"AM", 0}, // alpha variable memory
{"BU", 0}, // backup
{"DM", 0}, // defined memory
{"DD", 0}, // screenshot
{"EN", 0}, // one editor file
{"FN", 0}, // set of editor files
{"F1", 0}, // one function memory
{"F6", 0}, // set of function memories
{"GA", 0}, // set of graph functions
{"GF", 0}, // graph zoom factor (graph function?)
{"GR", 0}, // graph range
{"GT", 0}, // function table
{"MA", 0}, // set of matrices
{"PD", 0}, // polynomial equations
{"P1", 0}, // one program
{"PZ", 0}, // set of programs
{"RT", 0}, // recursion table
{"SD", 0}, // simultaneous equations
{"SR", 0}, // linear regression data
{"SS", 0}, // standard deviation data
/* implemented */
{"P1", g1m_mcstype_program, 0}, // one program
{"PZ", g1m_mcstype_program, g1m_mcsflag_multiple}, // set of programs
/* not implemented yet */
{"AA", 0, 0}, // dynamic graph functions
{"AD", 0, 0}, // variable memory
{"AL", 0, 0}, // all
{"AM", 0, 0}, // alpha variable memory
{"BU", 0, 0}, // backup
{"DM", 0, 0}, // defined memory
{"DD", 0, 0}, // screenshot
{"EN", 0, 0}, // one editor file
{"FN", 0, 0}, // set of editor files
{"F1", 0, 0}, // one function memory
{"F6", 0, 0}, // set of function memories
{"GA", 0, 0}, // set of graph functions
{"GF", 0, 0}, // graph zoom factor (graph function?)
{"GR", 0, 0}, // graph range
{"GT", 0, 0}, // function table
{"MA", 0, 0}, // set of matrices
{"PD", 0, 0}, // polynomial equations
{"RT", 0, 0}, // recursion table
{"SD", 0, 0}, // simultaneous equations
{"SR", 0, 0}, // linear regression data
{"SS", 0, 0}, // standard deviation data
/* terminating entry */
TTERM
@ -99,6 +102,7 @@ int g1m_maketype_cas(g1m_mcshead_t *head, const char *datatype)
/* fill in info and return */
head->type = c->type;
head->flags |= c->flags;
return (0);
notfound: