Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37549138
en ru br
ALT Linux repos
5.0: 4.64L-alt5.1
4.1: 4.64L-alt5
4.0: 4.64L-alt4.1
3.0: 4.58L-alt4
+backports:4.64L-alt0.M30.4

Group :: Networking/Mail
RPM: pine

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

recodeg.c0100644000076600007660000000664007657142534011346 0ustar  ivanivan/*
The recode table creator for multiply translations
Copyright (C) 1999 Lev Levitin <lev@mccme.ru>

Systemizing document and system-known charset names.
Enhancements.
Copyright (C) 2000-2003 Ivan Zakharyaschev <vanyaz@mccme.ru>
*/

/*#define FDEBUG*/

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "recodeg.h"

#include <pure_recode.h>
#include <chains.h>

struct Chain * recodeg_rules(void) {
static struct Chain * global_rules = NULL;
return global_rules ? : (global_rules = chain_createEmpty());
}


/* We do not need this function -- will pass the selected rules as
an argument in the place where the pipe is created. */
#if 0

#ifdef FDEBUG
#include <singleconv.h>
#endif

MultipleConverter *recodeg_pipe(void) {
#ifdef FDEBUG
MultipleConverter * result;
fprintf(stderr, __FUNCTION__ " start\n");
result = multiple_conv_open(rules()->first);
fprintf(stderr, __FUNCTION__ ": unused %d\n",
((SingleConverter *)result->first->value)->inbuf);
return result;
#else
return multiple_conv_open(recodeg_rules()->first);
#endif
}

#endif /* 0 */

#include <docconv.h>

int recodeg_addrule(const char *from, const char *to) {
return addRecodeRule(recodeg_rules(), from, to);
}

void recodeg_dellast(void) {
dellastRecodeRule(recodeg_rules());
}

void recodeg_delall(void) {
delallRecodeRules(recodeg_rules());
}

char * recodeg_info(void) {
return infoOnRecodeRules(recodeg_rules());
}

int recodeg_used(void) {
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
return ! chain_isEmpty(recodeg_rules());
}

static int auto_recode = 1;;

int recodeg_auto(void) {
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
return auto_recode;
}

void recodeg_setauto(int flag) {
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
auto_recode = flag;
}

#ifdef RECODEG_PINE

#include "headers.h"

void recodeg_autosolve(BODY *body) {
char *charset = rfc2231_get_param(body->parameter,
"charset", NULL, NULL);

#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif

recodeg_delall();
if(!charset)
return;

if( strucmp(charset, "us-ascii")
&& ps_global->VAR_CHAR_SET
&& strucmp(charset, ps_global->VAR_CHAR_SET))
{
recodeg_addrule(charset, ps_global->VAR_CHAR_SET);
}
fs_give((void **)&charset);

#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ " ret\n");
#endif
}

#endif

char * recodeg_validcharset(char * const in_charset) {
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
if (recodeg_used()) {
const char * const our_charset =
((const struct RecodeRule *)chain_last(recodeg_rules()))->to;
fs_give((void **) &in_charset);
return my_fs_dup(our_charset);
}
else
return in_charset;
}

const char * recodeg_validcharset_static(const char * const in_charset) {
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
if (recodeg_used()) {
const char * const our_charset =
((const struct RecodeRule *)chain_last(recodeg_rules()))->to;
return our_charset;
}
else
return in_charset;
}

/* Utility functions not related to recoding directly; */

char * my_fs_dup(const char * const S) {
const size_t l = strlen(S);
char * const copy = fs_get( (l+1) * sizeof(char) );
copy[l] = '\0';
strncpy(copy, S, l);
return copy;
}

char * my_fs_move(const char * const S) {
char * const copy = my_fs_dup(S);
free((char*)S);
return copy;
}
recodeg.h0100644000076600007660000000216407657142534011350 0ustar ivanivan/*
Recode Global interface: interface to information
about recoding for the whole process.

Copyright (C) 2001-2003 Ivan Zakharyaschev <imz@altlinux.ru>

It is similar to the interface defined by Lev.

The recode table creator for multiply translations
Copyright (C) 1999 Lev Levitin <lev@mccme.ru>
*/
#ifndef _RECODEG_H
#define _RECODEG_H

/* Utility functions not related to recoding directly; */

char * my_fs_dup(const char * S);
char * my_fs_move(const char * S);


#include <pure_recode.h>

struct Chain * recodeg_rules(void);

int recodeg_addrule(const char *from, const char *to);
void recodeg_dellast(void);
void recodeg_delall(void);
int recodeg_used(void);
int recodeg_auto(void);
void recodeg_setauto(int flag);

char * recodeg_info(void);
char * recodeg_validcharset(char *in_charset);
const char * recodeg_validcharset_static(const char *in_charset);

#ifdef RECODEG_PINE

/* This was added for PINE */
#include "headers.h"
void gf_recode(FILTER_S *, int);
int cmd_recode PROTO((struct pine *));
void recodeg_autosolve(BODY *body);

#define MC_RECODE 1000
#define MC_FMTSAVE 1001

#endif

#endif
my_util/0042755000076600007660000000000010200441725011231 5ustar ivanivanmy_util/Makefile0100644000076600007660000000070707400222671012675 0ustar ivanivanCPPFLAGS += -D_GNU_SOURCE
#CPPFLAGS += -DDEBUG

CFLAGS += -Wall

objs = lists.o chains.o buffers.o
lib = libmy_util.a


$(lib): $(objs)
clean::
-$(RM) $(objs)


%.a:
$(AR) rc $@ $^

clean::
-$(RM) $(lib)

######################################
# Various types of Cleaning

clean_cores::
-$(RM) *core

clean_after_emacs::
-$(RM) *'~'
-$(RM) '#'*'#'

distclean:: clean clean_after_emacs clean_cores

# End of Cleaning section
########################
my_util/LICENSE0100644000076600007660000000076407377703677012274 0ustar ivanivan(Public domain)

The permission to use, compile, modify, copy and ditribute this code
in any form is given to anyone. Anyone can put his own distribution
terms on a code derived from this.

I advise you to keep all the copyright notices and contributors'
names in your derived work based on this code.

No one is allowed to use the names of the copyright holders and
contributors for purposes different from stating that they are
the copyright holders and contributors without their permission.
my_util/buffers.c0100644000076600007660000000706607656453273013063 0ustar ivanivan#include "buffers.h"

/* Do not care about the maximum length of buffers: */
#define BUFFER_MAXLEN 0

/* A buffer grows by this number of bytes each time */
#define BUFFER_GROWSTEP 57


#include <stdlib.h>
#include <string.h>

struct CharBuffer * buffer_createEmpty(void) {
static const struct CharBuffer INITIAL
= { (char*)NULL,
(char*)NULL,
(char*)NULL,
(size_t)0
};
struct CharBuffer * const result = malloc(sizeof(struct CharBuffer));
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
if (result)
memcpy(result, &INITIAL, sizeof(struct CharBuffer));
return result;
}

struct CharBuffer * buffer_createMinimal(void) {
struct CharBuffer * result = buffer_createEmpty();
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
if (result)
if (! buffer_grow(result)) {
free(result);
result = NULL;
}
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "ret unused %d\n", result->unused);
#endif
return result;
}

void buffer_destroy(struct CharBuffer * const buf) {
if (buf->bulk)
free(buf->bulk);
free(buf);
}

#undef MIN
#define MIN(a,b) ( ( (a) < (b) ) ? (a) : (b) )

size_t buffer_grow(struct CharBuffer * const buf) {
size_t len = buf->after_used - buf->bulk + buf->unused;
size_t step = BUFFER_GROWSTEP;
size_t gap = buf->used - buf->bulk;
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
if (gap) {
memmove(buf->bulk, buf->used, buffer_used_len(buf));
buf->used = buf->bulk;
buf->after_used -= gap;
buf->unused += gap;
step -= gap;
}
if (! step)
return BUFFER_GROWSTEP;
if ( ! BUFFER_MAXLEN || ( len < BUFFER_MAXLEN ) ) {
/* the buffer grows until it's BUFFER_MAXLEN bytes long */
char * new;
step = (! BUFFER_MAXLEN) ? step : MIN(step, BUFFER_MAXLEN - len);
len += step;
new = realloc(buf->bulk, len * sizeof(char));
if (new) {
buf->after_used = new + (buf->after_used - buf->bulk);
buf->used = buf->bulk = new;
buf->unused += step;
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ " ret %d\n", step);
#endif
return step;
}
else
return 0;
}
}

short int buffer_putc(struct CharBuffer * const buf,
const char c)
{
return (buffer_puts(buf, &c, 1) != (size_t)0);
}

size_t buffer_puts(struct CharBuffer * const buf,
const char * s,
size_t s_len)
{
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ ": unused %d, used_len %d\n", buf->unused, buffer_used_len(buf));
#endif
while ( (buf->unused < s_len) && buffer_grow(buf) );
strncpy(buf->after_used, s, buf->unused);
buf->unused -= (s_len = MIN(buf->unused,s_len));
buf->after_used += s_len;
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ " returning: unused %d, used_len %d\n", buf->unused, buffer_used_len(buf));
#endif
return s_len;
}

short int buffer_isEmpty(const struct CharBuffer * const buf) {
return buf->used == buf->after_used;
}

#include <stdio.h>

int buffer_getc(struct CharBuffer * const buf)
{
if ( buffer_isEmpty(buf) )
return EOF;
else
return *(buf->used++);
}

size_t buffer_copyContents(const char ** const s,
const struct CharBuffer * const buf)
{
const size_t l = buffer_used_len(buf);
char * const dest = calloc(l, sizeof(char));
memcpy(dest, buf->used, l);
*s = dest;
return l;
}

#include <stdio.h>

void buffer_dump(const struct CharBuffer * const buf, FILE * f) {
if (! buffer_isEmpty(buf) )
fwrite(buf->used, sizeof(char), buffer_used_len(buf) , f);
}

size_t buffer_used_len(const struct CharBuffer * const buf) {
return buf->after_used - buf->used;
}
my_util/buffers.h0100644000076600007660000000143607656443664013066 0ustar ivanivan#ifndef _BUFFERS_H
#define _BUFFERS_H

#include <stdlib.h>

struct CharBuffer {
char * bulk,
* used,
* after_used;
size_t unused;
};

struct CharBuffer * buffer_createEmpty(void);
struct CharBuffer * buffer_createMinimal(void);
void buffer_destroy(struct CharBuffer * buf);

short int buffer_isEmpty(const struct CharBuffer * buf);
size_t buffer_used_len(const struct CharBuffer * const buf);

size_t buffer_grow(struct CharBuffer * buf);
short int buffer_putc(struct CharBuffer * buf, char c);
size_t buffer_puts(struct CharBuffer * buf, const char * s, size_t s_len);

int buffer_getc(struct CharBuffer * buf);
size_t buffer_copyContents(const char ** dest, const struct CharBuffer * buf);

#include <stdio.h>

void buffer_dump(const struct CharBuffer * const buf, FILE * f);

#endif
my_util/lists.c0100644000076600007660000000265707377702751012564 0ustar ivanivan/* lists.c
* Implementation of common basic actions on linked lists.
* Version 0.1, November 2001
*
* Copyright 2001 Ivan Zakharyaschev <imz@altlinux.ru>
*
* This code is in public domain: look LICENSE for more info.
*/

#include "lists.h"

#include <stdlib.h>

short int list_isEmptyList(const struct ListNode * const head) {
return head == NULL;
}

void * list_find(const struct ListNode * head,
const void * const key,
int (*cmp)(const void * key, const void * elem)
) {
for (; head != NULL; head = head->next)
if (cmp(key, head->value) == 0)
break;

return head ? head->value : NULL;
}

struct ListNode * list_add(struct ListNode * const head,
void * const elem) {
struct ListNode * new = malloc(sizeof(struct ListNode));
new->value = elem;
new->next = head;
return new;
}

#ifdef DEBUG
#include <stdio.h>
#endif

void list_walkThrough(const struct ListNode * head,
void (*action)(void * params, void * elem),
void * const params
) {
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
for (; head != NULL; head = head->next) {
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ ": performing action.\n");
#endif
action(params, head->value);
}
}

void list_destroy(struct ListNode * head,
void (* const destroyElem)(void * elem)
)
{
while (head) {
struct ListNode * next = head->next;
destroyElem(head->value);
free(head);
head = next;
}
}
my_util/lists.h0100644000076600007660000000145707377703147012566 0ustar ivanivan/* lists.c
* The interface of common basic actions on linked lists.
* Version 0.1, November 2001
*
* Copyright 2001 Ivan Zakharyaschev <imz@altlinux.ru>
*
* This code is in public domain: look LICENSE for more info.
*/

#ifndef _LISTS_H_
#define _LISTS_H_

struct ListNode {
void * value;
struct ListNode * next;
};

short int list_isEmptyList(const struct ListNode * head);

void * list_find(const struct ListNode * head,
const void * key,
int (*cmp)(const void * key, const void * elem)
);

struct ListNode * list_add(struct ListNode * head, void * elem);
void list_walkThrough(const struct ListNode * head,
void (*action)(void * params, void * elem),
void * params
);
void list_destroy(struct ListNode * head,
void (*destroyElem)(void * elem)
);

#endif
my_util/chains.c010064400007660000766 4157 10200441725 12524 0ustar ivanivan/* chains.c
* Basic actions on chains (list that can be appended)
*/

#include "chains.h"


#include <stdlib.h>

struct Chain * chain_createEmpty(void) {
struct Chain * result;
result = malloc(sizeof(struct Chain));
result->last = result->first = NULL;
return result;
}

short int chain_isEmpty(const struct Chain * const x) {
return x->first == NULL;
}

/* report if chain is empty: */
short int chain_verifyNotEmpty(const struct Chain *, const char *);

void chain_destroy(struct Chain * const x,
void (* const destroyElem)(void * elem))
{
list_destroy(x->first, destroyElem);
free(x);
}

struct Chain * chain_append(struct Chain * const x,
void * const a)
{
struct ListNode * newNode = malloc(sizeof(struct ListNode));
newNode->value = a;
newNode->next = NULL;

if ( chain_isEmpty(x) )
x->last = x->first = newNode;
else
x->last = x->last->next = newNode;
return x;
}

void * chain_first(const struct Chain * const x) {
return chain_verifyNotEmpty(x, __PRETTY_FUNCTION__) ?
x->first->value : NULL;
}

void * chain_last(const struct Chain * const x) {
return chain_verifyNotEmpty(x, __PRETTY_FUNCTION__) ?
x->last->value : NULL;
}

void chain_clear(struct Chain * const x,
void (* const destroyElem)(void * elem))
{
list_destroy(x->first, destroyElem);
x->last = x->first = NULL;
}

void * chain_dellast(struct Chain * const x) {
if ( chain_verifyNotEmpty(x, __PRETTY_FUNCTION__) ) {
void * result;
struct ListNode *node,
*prev = NULL;
for (node = x->first; node != x->last; node = node->next)
prev = node;
result = node->value;
free(node);
x->last = prev;
if (prev)
prev->next = NULL;
else
x->first = NULL;
return result;
}
else
return NULL;
}

/* The deifinitions of auxiliary functions: */

#include <stdio.h>

short int chain_verifyNotEmpty(const struct Chain * const x,
const char * const callerName)
{
const short int ok = ( ! chain_isEmpty(x) );
if ( ! ok ) {
fprintf(stderr,
"Invalid call to %s -- the chain is empty! Returning NULL.\n",
callerName);
}
return ok;
}
my_util/chains.h0100644000076600007660000000106307656525723012670 0ustar ivanivan#ifndef _CHAINS_H
#define _CHAINS_H

#include "lists.h"

struct Chain {
struct ListNode * first,
* last;
};

struct Chain * chain_createEmpty(void);
void chain_destroy(struct Chain * x, void (*destroyElem)(void * elem));

short int chain_isEmpty(const struct Chain * x);
void chain_clear(struct Chain * const x,
void (* const destroyElem)(void * elem));

struct Chain * chain_append(struct Chain * x, void * a);
void * chain_first(const struct Chain * x);
void * chain_last(const struct Chain * x);
void * chain_dellast(struct Chain * const x);

#endif
my_util/.emacs-backups/0042755000076600007660000000000010200441725014025 5ustar ivanivanmy_util/.emacs-backups/chains.c~0100644000076600007660000000372407400205672015644 0ustar ivanivan/* chains.c
* Basic actions on chains (list that can be appended)
*/

#include "chains.h"


#include <stdlib.h>

struct Chain * chain_createEmpty(void) {
struct Chain * result;
result = malloc(sizeof(struct Chain));
result->last = result->first = NULL;
return result;
}

short int chain_isEmpty(const struct Chain * const x) {
return x->first == NULL;
}

short int chain_verifyNotEmpty(const struct Chain * const x,
const char * const callerName)
{
const short int ok = chain_isEmpty(x);
if ( ! ok ) {
fprintf(stderr,
"Invalid call to %s -- the chain is empty! Returning NULL.\n",
callerName);
}
return ok;
}

void chain_destroy(struct Chain * const x,
void (* const destroyElem)(void * elem))
{
list_destroy(x->first, destroyElem);
free(x);
}

struct Chain * chain_append(struct Chain * const x,
void * const a)
{
struct ListNode * newNode = malloc(sizeof(struct ListNode));
newNode->value = a;
newNode->next = NULL;

if ( chain_isEmpty(x) )
x->last = x->first = newNode;
else
x->last = x->last->next = newNode;
return x;
}

#include <stdio.h>

void * chain_first(const struct Chain * const x) {
return chain_verifyNotEmpty(x, __PRETTY_FUNCTION__) ?
x->first->value : NULL;
}

void * chain_last(const struct Chain * const x) {
return chain_verifyNotEmpty(x, __PRETTY_FUNCTION__) ?
x->last->value : NULL;
}

void chain_clear(struct Chain * const x,
void (* const destroyElem)(void * elem))
{
list_destroy(x->first, destroyElem);
x->last = x->first = NULL;
}

void * chain_dellast(struct Chain * const x) {
if ( chain_verifyNotEmpty(x, __PRETTY_FUNCTION__) ) {
void * result;
struct ListNode *node,
*prev = NULL;
for (node = x->first; node != x->last; node = node->next)
prev = node;
result = node->value;
free(node);
x->last = prev;
if (prev)
prev->next = NULL;
else
x->first = NULL;
return result;
}
else
return NULL;
}
pure_recode/0042755000076600007660000000000007657135046012065 5ustar ivanivanpure_recode/Makefile0100644000076600007660000000265507400251514013511 0ustar ivanivanmy_util_dir = ../my_util

CPPFLAGS += -I$(my_util_dir)
CPPFLAGS += -D_GNU_SOURCE
#CPPFLAGS += -DDEBUG

CFLAGS += -Wall

#LOADLIBES +=

sources = multipleconv.c singleconv.c docconv.c test.c
objs = multipleconv.o singleconv.o docconv.o recoderules.o

my_util = $(my_util_dir)/libmy_util.a

tests = test
libs = pure_recode.a

all:: $(libs) $(tests)

####################################
# Automatic dependencies:

clean::
-$(RM) *.d

%.d: %.c
set -e; $(CC) -M $(CPPFLAGS) $< \
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
[ -s $@ ] || rm -f $@

ifeq ($(subst clean,,$(MAKECMDGOALS)),$(MAKECMDGOALS))
include $(sources:.c=.d)
endif

# End automatic deps
######################################

###################################
# Lib

%.a: $(objs)
$(AR) rc $@ $^

clean::
-$(RM) $(libs)

# end Lib
####################################

######################################
# Tests:

$(tests): $(objs) $(my_util)

clean_tests::
-$(RM) $(tests)

clean:: clean_tests

# End Tests
######################################

clean::
-$(RM) *.o

######################################
# Various types of Cleaning

clean_cores::
-$(RM) *core

clean_after_emacs::
-$(RM) *'~'
-$(RM) '#'*'#'

distclean:: clean clean_after_emacs clean_cores

# End of Cleaning section
########################


##########################################
# Other libs

$(my_util): .FORCE
(cd "$$(dirname $(my_util))"; $(MAKE) "$$(basename $(my_util))"; )

.FORCE:

pure_recode/docconv.c0100644000076600007660000000446307400017731013650 0ustar ivanivan/*
Systemizing document and system-known charset names.
2000 Ivan Zakharyaschev <vanyaz@mccme.ru>
*/
#include "docconv.h"

/**************************
Here comes a piece of code that resembles
"iconv" and is based on iconv, but is intended
for use with different codename arguments.

It could be a separate library.

Ivan Z.
*/

#include <iconv.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>


#ifndef SYSTEM_CHARSET_FOR
#define GET_SYSTEM_CHARSET_FOR(name) amateur_get_sys_charset(name)
#define FREE_SYSTEM_CHARSET(chrst) amateur_free_sys_charset(chrst)
#endif

char * amateur_get_sys_charset(const char * doc_charset);
void amateur_free_sys_charset(char * sys_charset);

docconv_t docconv_open(const char * const from, const char * const to) {
docconv_t result = malloc(sizeof(struct docconv));

result->to = GET_SYSTEM_CHARSET_FOR(to);
result->from = GET_SYSTEM_CHARSET_FOR(from);
result->ihandle = iconv_open(result->from, result->to);

if ( result->ihandle == (iconv_t) -1 ) {
FREE_SYSTEM_CHARSET(result->from);
FREE_SYSTEM_CHARSET(result->to);
return (docconv_t) -1;
}
return result;
}

int docconv_close(const docconv_t handle) {
int result;
if ( !handle || (handle == (docconv_t)-1) )
return -1;
FREE_SYSTEM_CHARSET(handle->from);
FREE_SYSTEM_CHARSET(handle->to);
result = iconv_close(handle->ihandle);
free(handle);
return result;
}

/* Should be replaced by a more general tool for
translating from document encoding names to character
set names known by the system. Ivan Z.
*/
char * amateur_get_sys_charset(const char * doc_charset) {
char *sys_charset = strdup(doc_charset),
*result = sys_charset;

/* Perhaps it doesn't belong here; maybe this should be done
before adding a rule. */
/* cut "x-" in front of charset name */
if(!strncasecmp(result,"x-",2))
result += 2;

/* translate windows- to cp, paratype- to pt */
if (!strncasecmp(result,"windows-",8)) {
result += 6;
result[0] = 'c'; result[1] = 'p';
}
else if (!strncasecmp(result,"paratype-",9)) {
result += 7;
result[0] = 'p'; result[1] = 't';
}

result = strdup(result);
free(sys_charset);

return result;
}

void amateur_free_sys_charset(char * sys_charset) {
free(sys_charset);
}

/* docconv finishes here
*****************************************/
pure_recode/docconv.h0100644000076600007660000000036307400022356013647 0ustar ivanivan#ifndef _DOCCONV_H
#define _DOCCONV_H

#include <iconv.h>

typedef struct docconv {
char *from, *to;
iconv_t ihandle;
} * docconv_t;

docconv_t docconv_open(const char * from, const char * to);
int docconv_close(docconv_t handle);

#endif
pure_recode/pure_recode.h0100644000076600007660000000236407656525301014526 0ustar ivanivan#ifndef _PURE_RECODE_H
#define _PURE_RECODE_H

#include <lists.h>
#include <chains.h>

struct RecodeRule {
const char *from,
*to;
} * createRecodeRule(const char * to, const char * from);
void destroyRecodeRule(struct RecodeRule * rule);


/* Contructing chains of rules: */

int addRecodeRule(struct Chain * const rules,
const char *from, const char *to);
void dellastRecodeRule(struct Chain * const rules);
void delallRecodeRules(struct Chain * const rules);
void destroyRecodeRules(struct Chain * const rules);
char * infoOnRecodeRules(const struct Chain * const rules);

/* Multiple converters: */

typedef struct Chain MultipleConverter;

#include <buffers.h>

MultipleConverter * multiple_conv_open(const struct ListNode * rules);

void multiple_conv_close(MultipleConverter * mc,
struct CharBuffer * outbuf);

void multiple_conv_feeds(const MultipleConverter * const mc,
const char * s,
size_t s_len,
struct CharBuffer * const outbuf);
void multiple_conv_feedc(const MultipleConverter * mc, char c,
struct CharBuffer * outbuf);

void multiple_conv_reset(MultipleConverter * mc,
struct CharBuffer * outbuf);


/* Higher level: */

char * multiple_conv_str(const struct Chain * const rules,
const char * const s);

#endif
pure_recode/recoderules.c0100644000076600007660000000462107656526065014547 0ustar ivanivan#include "pure_recode.h"

#include <stdlib.h>
#include <string.h>

struct RecodeRule * createRecodeRule(const char * const to,
const char * const from)
{
struct RecodeRule * result = malloc(sizeof(struct RecodeRule));
result->to = strdup(to);
result->from = strdup(from);
return result;
}

void destroyRecodeRule(struct RecodeRule * const rule) {
free((char*)rule->to);
free((char*)rule->from);
free(rule);
}


/* Contructing chains of rules: */

#include "docconv.h"

int addRecodeRule(struct Chain * const rules,
const char *from, const char *to)
{
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
{
docconv_t tmp;
if (
( from == NULL )
|| ( to == NULL )
|| ( (tmp = docconv_open(to, from)) == (docconv_t) -1 )
) {
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ ": bad\n");
#endif
return 1;
}
docconv_close(tmp);
}

{
struct RecodeRule *rule = createRecodeRule(to, from);
if(rule == NULL)
return 1;

chain_append(rules, rule);

#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ ": good\n");
#endif
return 0;
}
}

void dellastRecodeRule(struct Chain * const rules) {
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
if (! chain_isEmpty(rules) )
destroyRecodeRule(chain_dellast(rules));
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ " ret\n");
#endif
}

void delallRecodeRules(struct Chain * const rules) {
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
chain_clear(rules, (void(*)(void*))destroyRecodeRule);
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ ": ret\n");
#endif
}

void destroyRecodeRules(struct Chain * const rules) {
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
chain_destroy(rules, (void(*)(void*))destroyRecodeRule);
#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ ": ret\n");
#endif
}

char * infoOnRecodeRules(const struct Chain * const rules) {
void dumpRule(char ** const info,
const struct RecodeRule * const rule)
{
if (*info)
asprintf(info, "%s,%s->%s", *info, rule->from, rule->to);
else
asprintf(info, "%s->%s", rule->from, rule->to);
}

char * result = NULL;

#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif


if ( chain_isEmpty(rules) )
result = strdup("");
else
list_walkThrough(rules->first,
(void (*)(void * param, void * elem))&dumpRule,
&result);

#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ " ret\n");
#endif

return result;
}

pure_recode/test.c0100644000076600007660000000132607400205563013171 0ustar ivanivan#include <chains.h>
#include "pure_recode.h"
#include <stdio.h>
#include <buffers.h>

int main(int argc, char ** argv) {
struct Chain * rules = chain_createEmpty();
MultipleConverter * mc;
--argc;
while (argc) {
chain_append(rules, createRecodeRule(argv[2], argv[1]));
argv += 2; argc -= 2;
}
mc = multiple_conv_open(rules->first);

{
int c;
struct CharBuffer * buf = buffer_createEmpty();
while ( (c = getchar()) != EOF ) {
multiple_conv_feedc(mc, c, buf);
while (! buffer_isEmpty(buf))
putchar(buffer_getc(buf));
}
fflush(NULL);
buffer_destroy(buf);
}

multiple_conv_close(mc);
chain_destroy(rules, (void (*)(void * elem))&destroyRecodeRule);

return 0;
}
pure_recode/multipleconv.c0100644000076600007660000000671007656444571014756 0ustar ivanivan/*****************************************
* Multiple */
#include "pure_recode.h"
#include "singleconv.h"

#include <chains.h>
#include <lists.h>

void multiple_conv_feedc(const MultipleConverter * const mc,
const char c,
struct CharBuffer * const outbuf)
{
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
multiple_conv_feeds(mc, &c, 1, outbuf);
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ " ret\n");
#endif
}

void multiple_conv_feeds(const MultipleConverter * const mc,
const char * s,
const size_t s_len,
struct CharBuffer * const outbuf)
{
#define NEXT_BUF(next,outbuf) (\
next \
? ((SingleConverter *)next->value)->inbuf \
: outbuf \
)

struct ListNode
* node = NULL,
* next = mc->first;

#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
buffer_puts(NEXT_BUF(next,outbuf), s, s_len);
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ ": first puts done\n");
#endif
while (next) {
next = (node = next)->next;
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ " inbuf: unused %d, used_len %d\n", ((SingleConverter *)node->value)->inbuf->unused, buffer_used_len(((SingleConverter *)node->value)->inbuf));
#endif
single_conva_force((SingleConverter *)node->value, NEXT_BUF(next,outbuf));
}
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ ": return.\n");
#endif
}

#include <stdlib.h>

MultipleConverter * multiple_conv_open(const struct ListNode * const rules) {
void appendConverter(struct Chain * const chain,
const struct RecodeRule * const rule)
{
SingleConverter * sc = single_conv_open(rule->to, rule->from);
if (sc != NULL)
chain_append(chain, sc);
}

MultipleConverter * result = chain_createEmpty();
list_walkThrough(rules,
(void (*)(void * param, void * elem))&appendConverter,
result);

return result;
}

void multiple_conv_close_internal(MultipleConverter * mc) {
void closeConverter(const void * const p, SingleConverter * const sc) {
single_conv_close(sc);
}
list_walkThrough(mc->first,
(void (*)(void * param, void * elem))&closeConverter ,
NULL);
}

void multiple_conv_close(MultipleConverter * mc,
struct CharBuffer * const outbuf)
{
multiple_conv_reset(mc, outbuf);
multiple_conv_close_internal(mc);
}

void multiple_conv_reset(MultipleConverter * mc,
struct CharBuffer * const outbuf)
{
struct ListNode
* node = NULL,
* next = mc->first;

#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
while (next) {
next = (node = next)->next;
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ " inbuf: unused %d, used_len %d\n", ((SingleConverter *)node->value)->inbuf->unused, buffer_used_len(((SingleConverter *)node->value)->inbuf));
#endif
single_conva_reset((SingleConverter *)node->value, NEXT_BUF(next,outbuf));
}
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ ": return.\n");
#endif
}


/* Higher level: */

#include <buffers.h>
#include <string.h>

char * multiple_conv_str(const struct Chain * const rules,
const char * const s) {
char * result = NULL;
MultipleConverter * const pipe = multiple_conv_open(rules->first);
struct CharBuffer * const buf = buffer_createEmpty();

#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif

multiple_conv_feeds(pipe, s, strlen(s), buf);
multiple_conv_close(pipe, buf);
buffer_putc(buf, '\0');
buffer_copyContents((const char**)&result, buf);
buffer_destroy(buf);

#ifdef FDEBUG
fprintf(stderr, __FUNCTION__ " ret\n");
#endif

return result;
}

pure_recode/singleconv.c0100644000076600007660000000711207656444423014375 0ustar ivanivan#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include <iconv.h>

#include <buffers.h>

#define ASCII_ERRS "?"

size_t iconva(const iconv_t icd,
char ** const inbuf, size_t * const inleft,
struct CharBuffer * const outbuf)
{
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
do {
size_t result;
if ( ! outbuf->unused )
buffer_grow(outbuf);
#ifdef DEBUG
if (inbuf)
fprintf(stderr, __FUNCTION__ ": about iconv, left %d\n", *inleft);
else
fprintf(stderr, __FUNCTION__ ": about iconv, RESET\n");

#endif
result = iconv(icd, inbuf, inleft,
&outbuf->after_used, &outbuf->unused);
#ifdef DEBUG
if (inbuf)
fprintf(stderr, __FUNCTION__ ": iconv == %d, left %d\n", result, *inleft);
else
fprintf(stderr, __FUNCTION__ ": iconv == %d, RESET\n", result);

#endif
if ( ( result != (size_t) -1 )
|| ( errno != E2BIG)
|| ! buffer_grow(outbuf)
)
return result;
} while (1);
}

size_t iconva_reset(const iconv_t icd, struct CharBuffer * const outbuf)
{
return iconva(icd, NULL, NULL, outbuf);
}

/******************************************
* Single converter */

#include "singleconv.h"
#include "docconv.h"

size_t single_conva(const SingleConverter * const sc,
struct CharBuffer * const outbuf)
{
size_t in_left = buffer_used_len(sc->inbuf);
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ ": about iconv, left %d\n", in_left);
#endif
return iconva(sc->icd, &sc->inbuf->used, &in_left, outbuf);
}

void single_conv_putErr(const SingleConverter * const sc,
struct CharBuffer * const outbuf)
{
iconva_reset(sc->icd, outbuf);
if (sc->errs)
buffer_puts(outbuf, sc->errs, sc->errlen);
}

void single_conva_reset(const SingleConverter * const sc,
struct CharBuffer * const outbuf)
{
iconva_reset(sc->icd, outbuf);
}

void single_conva_force(const SingleConverter * const sc,
struct CharBuffer * const outbuf)
{
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ "\n");
#endif
while ( ! buffer_isEmpty(sc->inbuf)
&& ( single_conva(sc, outbuf) == (size_t) -1 )
&& ( errno == EILSEQ )
)
{
single_conv_putErr(sc, outbuf);
buffer_getc(sc->inbuf);
}
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ ": returning.\n");
#endif
}

SingleConverter * single_conv_open(const char * const to,
const char * const from)
{
SingleConverter * result = malloc(sizeof(SingleConverter));

result->dcd = docconv_open(to, from);
if (result->dcd == (docconv_t) -1) {
free(result);
return NULL;
}
result->icd = result->dcd->ihandle;
result->inbuf = buffer_createMinimal();
#ifdef DEBUG
fprintf(stderr, __FUNCTION__ ": unused %d.\n", result->inbuf->unused);
#endif
{
docconv_t dcd = docconv_open(to, "us-ascii");
if (dcd == (docconv_t) -1) {
result->errs = "";
result->errlen = 0;
}
else {
char * ascii_errs = ASCII_ERRS;
size_t ascii_errs_len = strlen(ASCII_ERRS);
struct CharBuffer * buf = buffer_createMinimal();
iconva(result->dcd->ihandle, &ascii_errs, &ascii_errs_len, buf);
iconva_reset(result->dcd->ihandle, buf);
docconv_close(dcd);
result->errlen = buffer_copyContents(&result->errs, buf);
buffer_destroy(buf);
}
}

#ifdef DEBUG
fprintf(stderr, __FUNCTION__ ": ret unused %d.\n", result->inbuf->unused);
#endif
return result;
}

void single_conv_close(SingleConverter * const sc) {
buffer_destroy(sc->inbuf);
docconv_close(sc->dcd);
if (sc->errs)
free((char*)sc->errs);
}

/* End of single converter definitions
****************************************/

pure_recode/singleconv.h0100644000076600007660000000107507400233212014357 0ustar ivanivan#include <buffers.h>
#include <iconv.h>
#include "docconv.h"

typedef struct {
struct CharBuffer * inbuf;
iconv_t icd;
docconv_t dcd;
const char * errs;
size_t errlen;
} SingleConverter;

SingleConverter * single_conv_open(const char * to, const char * from);
void single_conv_close(SingleConverter * sc);

size_t single_conva(const SingleConverter * sc,
struct CharBuffer * outbuf);
void single_conva_force(const SingleConverter * sc,
struct CharBuffer * outbuf);
void single_conva_reset(const SingleConverter * sc,
struct CharBuffer * outbuf);
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin