[Po4a-commits] "po4a/extension/lib/Locale/Po4a Man.xs, NONE,
1.1 Po.h, NONE, 1.1 Po.xs, NONE, 1.1 TransTractor.xs, NONE,
1.1 hash.h, NONE, 1.1 message.h, NONE, 1.1 pos.h, NONE,
1.1 str-list.h, NONE, 1.1"
Nicolas FRANCOIS
nekral-guest at alioth.debian.org
Sat Mar 24 13:04:46 CET 2007
- Previous message: [Po4a-commits] "po4a/extension Build.PL,NONE,1.1 typemap,NONE,1.1"
- Next message: [Po4a-commits] "po4a/lib/Locale/Po4a Man.pm, 1.196, 1.197 Po.pm,
1.72, 1.73 TransTractor.pm, 1.90, 1.91"
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/po4a/po4a/extension/lib/Locale/Po4a
In directory alioth:/tmp/cvs-serv14975/extension/lib/Locale/Po4a
Added Files:
Man.xs Po.h Po.xs TransTractor.xs hash.h message.h pos.h
str-list.h
Log Message:
New C extension. Not built or distributed by default.
--- NEW FILE: pos.h ---
/* Source file positions.
Copyright (C) 1995-1998, 2000-2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _POS_H
#define _POS_H
/* Get size_t. */
#include <stddef.h>
/* Position of a message within a source file.
Used for error reporting purposes. */
typedef struct lex_pos_ty lex_pos_ty;
struct lex_pos_ty
{
char *file_name;
size_t line_number;
};
#endif /* _POS_H */
--- NEW FILE: hash.h ---
/* Copyright (C) 1995, 2000-2003, 2005-2006 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street,
Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _HASH_H
#define _HASH_H
#include "obstack.h"
#ifdef __cplusplus
extern "C" {
#endif
struct hash_entry;
typedef struct hash_table
{
unsigned long int size; /* Number of allocated entries. */
unsigned long int filled; /* Number of used entries. */
struct hash_entry *first; /* Pointer to head of list of entries. */
struct hash_entry *table; /* Pointer to array of entries. */
struct obstack mem_pool; /* Memory pool holding the keys. */
}
hash_table;
/* Initialize a hash table. INIT_SIZE > 1 is the initial number of available
entries.
Return 0 upon successful completion, -1 upon memory allocation error. */
extern int hash_init (hash_table *htab, unsigned long int init_size);
/* Delete a hash table's contents.
Return 0 always. */
extern int hash_destroy (hash_table *htab);
/* Look up the value of a key in the given table.
If found, return 0 and set *RESULT to it. Otherwise return -1. */
extern int hash_find_entry (hash_table *htab,
const void *key, size_t keylen,
void **result);
/* Try to insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table.
Return non-NULL (more precisely, the address of the KEY inside the table's
memory pool) if successful, or NULL if there is already an entry with the
given key. */
extern const void * hash_insert_entry (hash_table *htab,
const void *key, size_t keylen,
void *data);
/* Insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table.
Return 0. */
extern int hash_set_value (hash_table *htab,
const void *key, size_t keylen,
void *data);
/* Steps *PTR forward to the next used entry in the given hash table. *PTR
should be initially set to NULL. Store information about the next entry
in *KEY, *KEYLEN, *DATA.
Return 0 normally, -1 when the whole hash table has been traversed. */
extern int hash_iterate (hash_table *htab, void **ptr,
const void **key, size_t *keylen,
void **data);
/* Steps *PTR forward to the next used entry in the given hash table. *PTR
should be initially set to NULL. Store information about the next entry
in *KEY, *KEYLEN, *DATAP. *DATAP is set to point to the storage of the
value; modifying **DATAP will modify the value of the entry.
Return 0 normally, -1 when the whole hash table has been traversed. */
extern int hash_iterate_modify (hash_table *htab, void **ptr,
const void **key, size_t *keylen,
void ***datap);
/* Given SEED > 1, return the smallest odd prime number >= SEED. */
extern unsigned long int next_prime (unsigned long int seed);
#ifdef __cplusplus
}
#endif
#endif /* not _HASH_H */
--- NEW FILE: message.h ---
/* GNU gettext - internationalization aids
Copyright (C) 1995-1998, 2000-2006 Free Software Foundation, Inc.
This file was written by Peter Miller <millerp at canb.auug.org.au>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _MESSAGE_H
#define _MESSAGE_H
#include "str-list.h"
#include "pos.h"
#include "hash.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* According to Sun's Uniforum proposal the default message domain is
named 'messages'. */
#define MESSAGE_DOMAIN_DEFAULT "messages"
/* Separator between msgctxt and msgid in .mo files. */
#define MSGCTXT_SEPARATOR '\004' /* EOT */
/* Kinds of format strings. */
enum format_type
{
format_c,
format_objc,
format_sh,
format_python,
format_lisp,
format_elisp,
format_librep,
format_scheme,
format_smalltalk,
format_java,
format_csharp,
format_awk,
format_pascal,
format_ycp,
format_tcl,
format_perl,
format_perl_brace,
format_php,
format_gcc_internal,
format_qt,
format_boost
};
#define NFORMATS 21 /* Number of format_type enum values. */
//extern DLL_VARIABLE const char *const format_language[NFORMATS];
//extern DLL_VARIABLE const char *const format_language_pretty[NFORMATS];
extern const char *const format_language[NFORMATS];
extern const char *const format_language_pretty[NFORMATS];
/* Is current msgid a format string? */
enum is_format
{
undecided,
yes,
no,
yes_according_to_context,
possible,
impossible
};
extern bool
possible_format_p (enum is_format);
/* Is current msgid wrappable? */
#if 0
enum is_wrap
{
undecided,
yes,
no
};
#else /* HACK - C's enum concept is so stupid */
#define is_wrap is_format
#endif
typedef struct message_ty message_ty;
struct message_ty
{
/* The msgctxt string, if present. */
const char *msgctxt;
/* The msgid string. */
const char *msgid;
/* The msgid's plural, if present. */
const char *msgid_plural;
/* The msgstr strings. */
const char *msgstr;
/* The number of bytes in msgstr, including the terminating NUL. */
size_t msgstr_len;
/* Position in the source PO file. */
lex_pos_ty pos;
/* Plain comments (#) appearing before the message. */
string_list_ty *comment;
/* Extracted comments (#.) appearing before the message. */
string_list_ty *comment_dot;
/* File position comments (#:) appearing before the message, one for
each unique file position instance, sorted by file name and then
by line. */
size_t filepos_count;
lex_pos_ty *filepos;
/* Informations from special comments (e.g. generated by msgmerge). */
bool is_fuzzy;
enum is_format is_format[NFORMATS];
/* Do we want the string to be wrapped in the emitted PO file? */
enum is_wrap do_wrap;
/* The prev_msgctxt, prev_msgid and prev_msgid_plural strings appearing
before the message, if present. Generated by msgmerge. */
const char *prev_msgctxt;
const char *prev_msgid;
const char *prev_msgid_plural;
/* If set the message is obsolete and while writing out it should be
commented out. */
bool obsolete;
/* Used for checking that messages have been used, in the msgcmp,
msgmerge, msgcomm and msgcat programs. */
int used;
/* Used for looking up the target message, in the msgcat program. */
message_ty *tmp;
/* Used for combining alternative translations, in the msgcat program. */
int alternative_count;
struct altstr
{
const char *msgstr;
size_t msgstr_len;
const char *msgstr_end;
string_list_ty *comment;
string_list_ty *comment_dot;
char *id;
}
*alternative;
};
extern message_ty *
message_alloc (const char *msgctxt,
const char *msgid, const char *msgid_plural,
const char *msgstr, size_t msgstr_len,
const lex_pos_ty *pp);
#define is_header(mp) ((mp)->msgctxt == NULL && (mp)->msgid[0] == '\0')
extern void
message_free (message_ty *mp);
extern void
message_comment_append (message_ty *mp, const char *comment);
extern void
message_comment_dot_append (message_ty *mp, const char *comment);
extern void
message_comment_filepos (message_ty *mp, const char *name, size_t line);
extern message_ty *
message_copy (message_ty *mp);
typedef struct message_list_ty message_list_ty;
struct message_list_ty
{
message_ty **item;
size_t nitems;
size_t nitems_max;
bool use_hashtable;
hash_table htable; /* Table mapping msgid to 'message_ty *'. */
};
/* Create a fresh message list.
If USE_HASHTABLE is true, a hash table will be used to speed up
message_list_search(). USE_HASHTABLE can only be set to true if it is
known that the message list will not contain duplicate msgids. */
extern message_list_ty *
message_list_alloc (bool use_hashtable);
/* Free a message list.
If keep_messages = 0, also free the messages. If keep_messages = 1, don't
free the messages. */
extern void
message_list_free (message_list_ty *mlp, int keep_messages);
extern void
message_list_append (message_list_ty *mlp, message_ty *mp);
extern void
message_list_prepend (message_list_ty *mlp, message_ty *mp);
extern void
message_list_insert_at (message_list_ty *mlp, size_t n, message_ty *mp);
extern void
message_list_delete_nth (message_list_ty *mlp, size_t n);
typedef bool message_predicate_ty (const message_ty *mp);
extern void
message_list_remove_if_not (message_list_ty *mlp,
message_predicate_ty *predicate);
/* Recompute the hash table of a message list after the msgids or msgctxts
changed. */
extern bool
message_list_msgids_changed (message_list_ty *mlp);
extern message_ty *
message_list_search (message_list_ty *mlp,
const char *msgctxt, const char *msgid);
extern message_ty *
message_list_search_fuzzy (message_list_ty *mlp,
const char *msgctxt, const char *msgid);
typedef struct message_list_list_ty message_list_list_ty;
struct message_list_list_ty
{
message_list_ty **item;
size_t nitems;
size_t nitems_max;
};
extern message_list_list_ty *
message_list_list_alloc (void);
/* Free a list of message lists.
If keep_level = 0, also free the messages. If keep_level = 1, don't free
the messages but free the lists. If keep_level = 2, don't free the
the messages and the lists. */
extern void
message_list_list_free (message_list_list_ty *mllp, int keep_level);
extern void
message_list_list_append (message_list_list_ty *mllp,
message_list_ty *mlp);
extern void
message_list_list_append_list (message_list_list_ty *mllp,
message_list_list_ty *mllp2);
extern message_ty *
message_list_list_search (message_list_list_ty *mllp,
const char *msgctxt, const char *msgid);
extern message_ty *
message_list_list_search_fuzzy (message_list_list_ty *mllp,
const char *msgctxt, const char *msgid);
typedef struct msgdomain_ty msgdomain_ty;
struct msgdomain_ty
{
const char *domain;
message_list_ty *messages;
};
extern msgdomain_ty *
msgdomain_alloc (const char *domain, bool use_hashtable);
extern void
msgdomain_free (msgdomain_ty *mdp);
typedef struct msgdomain_list_ty msgdomain_list_ty;
struct msgdomain_list_ty
{
msgdomain_ty **item;
size_t nitems;
size_t nitems_max;
bool use_hashtable;
const char *encoding; /* canonicalized encoding or NULL if unknown */
};
extern msgdomain_list_ty *
msgdomain_list_alloc (bool use_hashtable);
extern void
msgdomain_list_free (msgdomain_list_ty *mdlp);
extern void
msgdomain_list_append (msgdomain_list_ty *mdlp, msgdomain_ty *mdp);
extern void
msgdomain_list_append_list (msgdomain_list_ty *mdlp,
msgdomain_list_ty *mdlp2);
extern message_list_ty *
msgdomain_list_sublist (msgdomain_list_ty *mdlp, const char *domain,
bool create);
extern message_ty *
msgdomain_list_search (msgdomain_list_ty *mdlp,
const char *msgctxt, const char *msgid);
extern message_ty *
msgdomain_list_search_fuzzy (msgdomain_list_ty *mdlp,
const char *msgctxt, const char *msgid);
/* The goal function used in fuzzy search.
Higher values indicate a closer match. */
extern double
fuzzy_search_goal_function (const message_ty *mp,
const char *msgctxt, const char *msgid);
/* The threshold for fuzzy-searching.
A message is considered only if fstrcmp (msg, given) > FUZZY_THRESHOLD. */
#define FUZZY_THRESHOLD 0.6
#ifdef __cplusplus
}
#endif
#endif /* message.h */
--- NEW FILE: Po.xs ---
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
//#include "ppport.h"
//#include "const-c.inc"
#include "Po.h"
Locale_Po4a_Po Po_new(char *class)
{
struct Po *ret;
printf("Locale::Po4a::Po::new()\n");
ret = (struct Po *)safemalloc(sizeof(struct Po));
// ret->po_file = NULL;
ret->mlp = NULL;
return ret;
}
void Po_DESTROY(Locale_Po4a_Po self)
{
printf("Locale::Po4a::Po::DESTROY\n");
// if (NULL != self->po_file)
// po_file_free(self->po_file);
if (NULL != self->mlp)
message_list_free(self->mlp, 0);
safefree(self);
}
void Po_read(Locale_Po4a_Po self, char *filename)
{
printf("Locale::Po4a::Po::read(%s)\n", filename);
// self->po_file = po_file_read(filename, &default_xerror_handler);
po_file_t po_file = po_file_read(filename, &default_xerror_handler);
self->mlp = message_list_alloc (true);
#if 0
FILE * fp = fopen(filename, "r");
extract_po(fp,
filename, /* real file name */
filename, /* logical file name */
NULL, /* not applicable for PO files */
self->mdlp);
if (fp != stdin)
fclose (fp);
#endif
if (po_file == NULL)
croak("Can't open the PO file %s", filename);
else
{
po_message_iterator_t iterator = po_message_iterator (po_file, NULL);
for (;;)
{
po_message_t message = po_next_message (iterator);
if (message == NULL)
break;
else
message_list_append (self->mlp, (message_ty *)message);
}
po_message_iterator_free (iterator);
}
// No free, otherwise, the messages are freed.
// po_file_free (po_file);
}
int debug(char *key, int klen)
{
int ret = 0;
HV* debug = get_hv("debug", FALSE);
if (NULL != debug)
{
SV **svp = hv_fetch(debug, key, klen, FALSE);
if (NULL != svp)
{
SV *sv = *svp;
if (0 != SvIV(sv))
ret = 1;
}
}
return ret;
}
#define KEY(x) x, sizeof(x)-1
char *Po_escape_text(char *text)
{
char *pc = text;
unsigned int len = 0;
// int need_escape = 0;
char *ret;
char *pc_ret;
int debug_escape = debug(KEY("escape"));
if (debug_escape)
fprintf(stderr, "\nescape [%s]====", text);
while (*pc != '\0')
{
switch (*pc)
{
case '\\':
case '\"':
case '\n':
case '\t':
len += 2;
// need_escape = 1;
break;
default:
len++;
}
pc++;
}
// if (0 == need_escape)
// return text;
Newx(ret, len+1, char);
pc_ret = ret;
pc = text;
while (*pc != '\0')
{
switch (*pc)
{
case '\\':
*pc_ret++ = '\\';
*pc_ret++ = '\\';
break;
case '"':
*pc_ret++ = '\\';
*pc_ret++ = '"';
break;
case '\n':
*pc_ret++ = '\\';
*pc_ret++ = 'n';
break;
case '\t':
*pc_ret++ = '\\';
*pc_ret++ = 't';
break;
default:
*pc_ret++ = *pc;
}
pc++;
}
*pc_ret = '\0';
if (debug_escape)
fprintf(stderr, ">%s<\n", ret);
return ret;
}
char *Po_unescape_text(char *text)
{
char *ret;
char *pc = text;
char *pc_ret;
int debug_escape = debug(KEY("escape"));
if (debug_escape)
fprintf(stderr, "\nunescape [%s]====", text);
Newx(ret, strlen(text)+1, char);
pc_ret = ret;
while (*pc != '\0')
{
if (*pc != '\\')
*pc_ret++ = *pc++;
else if (*pc == '\n')
continue;
else switch (pc[1])
{
case '\0':
*pc_ret++ = *++pc;
break;
case 'n':
*pc_ret++ = '\n';
pc += 2;
break;
case 't':
*pc_ret++ = '\t';
pc += 2;
break;
case '"':
*pc_ret++ = '"';
pc += 2;
break;
case '\\':
*pc_ret++ = '\\';
pc += 2;
break;
default:
printf("unescape sequence ?: '%c'\n", pc[1]);
}
}
*pc_ret = '\0';
if (debug_escape)
fprintf(stderr, ">%s<\n", ret);
return ret;
}
char *Po_unquote_text(char *text)
{
char *ret;
char *pc = text;
char *pc_ret;
int debug_quote = debug(KEY("quote"));
if (debug_quote)
fprintf(stderr, "\nunquote [%s]====\n", text);
Newx(ret, strlen(text)+1, char);
pc_ret = ret;
if (pc[0] == '"' && pc[1] == '"' && pc[2] == '\n')
pc += 3;
if (pc[0] == '"')
pc++;
while (*pc != '\0')
{
if (pc[0] == '"' && pc[1] == '\0')
pc++;
else if (pc[0] == '"' && pc[1] == '\n' && pc[2] == '"')
pc += 3;
else if (pc[0] == '\\' && pc[1] == 'n' && pc[2] == '\n')
{
*pc_ret++ = '\\';
*pc_ret++ = 'n';
pc += 3;
}
else
{
*pc_ret++ = *pc++;
}
}
*pc_ret = '\0';
if (debug_quote)
fprintf(stderr, ">%s<\n", ret);
return ret;
}
char *Po_canonize(char *text)
{
char *ret;
char *pc = text;
char *pc_ret;
int len = strlen(text)+1;
int debug_canonize = debug(KEY("canonize"));
if (debug_canonize)
fprintf(stderr, "\ncanonize [%s]====\n", text);
while(*pc != '\0')
{
if (*pc == '.' || *pc == '(')
len++;
pc++;
}
pc = text;
Newx(ret, len, char);
pc_ret = ret;
while (*pc == ' ')
pc++;
/*
if (*pc == '\t')
{
*pc_ret++ = ' ';
*pc_ret++ = ' ';
while (*pc == ' ' || *pc == '\t')
pc++;
}
*/
while (*pc != '\0')
{
if (pc_ret != ret)
{
/* already one char in ret */
if (pc[0] == '\n')
{
if (pc_ret[-1] == ')' || pc_ret[-1] == '.')
{
*pc_ret++ = ' ';
*pc_ret++ = ' ';
}
else if (pc_ret[-1] != ' ' || pc_ret[-2] == ')' || pc_ret[-2] == '.')
{
*pc_ret++ = ' ';
}
pc++;
}
else if (pc[0] == ' '/* || pc[0] == '\t'*/)
{
if (pc_ret[-1] == ' ')
{
if (pc_ret >= ret+2 && (pc_ret[-2] == ')' || pc_ret[-2] == '.'))
{
*pc_ret++ = ' ';
}
}
else
{
*pc_ret++ = ' ';
}
pc++;
}
else
*pc_ret++ = *pc++;
}
else
*pc_ret++ = *pc++;
}
do
{
*pc_ret-- = '\0';
}
while (*pc_ret == ' ');
if (debug_canonize)
fprintf(stderr, ">%s<\n", ret);
return ret;
}
/*
char *quote_text(char *text)
{
char *ret;
int debug_escape = debug(KEY("escape"));
if (debug_escape)
fprintf(stderr, "\nquote [%s]====", text);
if (debug_escape)
fprintf(stderr, ">%s<\n", ret);
return ret;
}
*/
char *Po_get_charset(SV* self)
{
char *ret;
char *header;
STRLEN headerlen;
SV* self_sv;
SV** psv;
SV* string;
STRLEN header_len;
if(!SvOK(self) || !SvROK(self)) goto error;
self_sv = SvRV(self);
if(SvTYPE(self_sv) != SVt_PVHV) goto error;
psv = hv_fetch((HV *)self_sv, "header", 6, 0);
if(psv == NULL) goto error;
string = *psv;
//fprintf(stderr, "get_charset3 %p %s\n", string, SvPV_nolen(string));
if(!SvPOK(string)) goto error;
//fprintf(stderr, "get_charset4\n");
header = SvPV(string, headerlen);
char *charset = strstr(header, "charset=");
if (NULL == charset)
{
fprintf(stderr, "no charset found\n");
ret = strdup("");
}
else
{
charset += 8; /* remove "charset=" */
char *pc = charset;
while ( pc < header + headerlen
&& *pc != ' '
&& *pc != '\t'
&& *pc != '\n'
&& *pc != '\\')
{
pc++;
}
Newx(ret, pc - charset+1, char);
memcpy(ret, charset, pc - charset);
ret[pc - charset] = '\0';
}
return ret;
error:
croak("can't extract charset.");
}
/*
self new(this, options)
char *timezone()
initialize(self,options)
read(self, filename)
write(self, filename)
write_if_needed(self, filename)
move_po_if_needed(new_po, old_po, backup)
gettextize(this, class)
filter(self, filter)
to_utf8(self)
gettext(self, text, options)
stats_get(self)
stats_clear(self)
push(self, entry)
push_raw(self, entry)
int count_enties(self)
int count_entries_doc(self)
char *msgid(self, num)
char *msgid_doc(self, num)
set_charset(self, charset)
char *quote_text(string)
char *wrap(text)
char *format_comment(comment, c)
*/
MODULE = Locale::Po4a::Po PACKAGE = Locale::Po4a::Po PREFIX = Po_
char *
Po_escape_text(text)
char * text
char *
Po_unescape_text(text)
char * text
char *
Po_get_charset(self)
SV * self
char *
Po_unquote_text(text)
char * text
char *
Po_canonize(text)
char * text
Locale_Po4a_Po
Po_new(class)
char * class
void
Po_DESTROY(self)
Locale_Po4a_Po self
void
Po_read(self, filename)
Locale_Po4a_Po self
char * filename
void
Po_push(self, ...)
Locale_Po4a_Po self
CODE:
char *msgid = NULL;
char *msgstr = NULL;
char *reference = NULL;
char *comment = NULL;
char *automatic = NULL;
char *flags = NULL;
char *type = NULL;
int i = items;
printf("Locale::Po4a::Po::push()\n");
if ((items % 2) == 0)
croak("Usage: Locale::Po4a::Po::push(self, k => v, ...)\n");
for (i=1; i<items; i+=2)
{
char *key = SvPV_nolen(ST(i));
if (strEQ(key, "msgid"))
msgid = SvPV_nolen(ST(i+1));
else if (strEQ(key, "msgstr"))
msgstr = SvPV_nolen(ST(i+1));
else if (strEQ(key, "reference"))
reference = SvPV_nolen(ST(i+1));
else if (strEQ(key, "comment"))
comment = SvPV_nolen(ST(i+1));
else if (strEQ(key, "automatic"))
automatic = SvPV_nolen(ST(i+1));
else if (strEQ(key, "flags"))
flags = SvPV_nolen(ST(i+1));
else if (strEQ(key, "type"))
type = SvPV_nolen(ST(i+1));
else
croak("Unknown key found in Locale::Po4a::Po::push: %s\n",
SvPV_nolen(ST(i)));
}
/* message_list_search, message_list_append, message_alloc */
message_ty *mp1 = message_list_search(self->mlp, NULL, msgid);
printf("push search: %p\n", mp1);
lex_pos_ty pos = { "file", 0 /*line*/};
message_ty *mp2 = message_alloc(NULL, /* msgctxt */
msgid,
NULL, /* No plural */
msgstr,
strlen (msgstr) + 1,
&pos);
if (NULL == mp1)
{
message_list_append(self->mlp, mp2);
}
else
{
if (!strEQ(msgstr, mp1->msgstr))
printf("duplicate: msgid: \"%s\", msgstr: \"%s\"/\"%s\"\n",
msgid, msgstr, mp1->msgstr);
}
--- NEW FILE: str-list.h ---
/* GNU gettext - internationalization aids
Copyright (C) 1995-1996, 1998, 2000-2004 Free Software Foundation, Inc.
This file was written by Peter Miller <millerp at canb.auug.org.au>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _STR_LIST_H
#define _STR_LIST_H 1
/* Get size_t and NULL. */
#include <stddef.h>
/* Get bool. */
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Type describing list of immutable strings,
implemented using a dynamic array. */
typedef struct string_list_ty string_list_ty;
struct string_list_ty
{
const char **item;
size_t nitems;
size_t nitems_max;
};
/* Initialize an empty list of strings. */
extern void string_list_init (string_list_ty *slp);
/* Return a fresh, empty list of strings. */
extern string_list_ty *string_list_alloc (void);
/* Append a single string to the end of a list of strings. */
extern void string_list_append (string_list_ty *slp, const char *s);
/* Append a single string to the end of a list of strings, unless it is
already contained in the list. */
extern void string_list_append_unique (string_list_ty *slp, const char *s);
/* Destroy a list of strings. */
extern void string_list_destroy (string_list_ty *slp);
/* Free a list of strings. */
extern void string_list_free (string_list_ty *slp);
/* Return a freshly allocated string obtained by concatenating all the
strings in the list. */
extern char *string_list_concat (const string_list_ty *slp);
/* Return a freshly allocated string obtained by concatenating all the
strings in the list, and destroy the list. */
extern char *string_list_concat_destroy (string_list_ty *slp);
/* Return a freshly allocated string obtained by concatenating all the
strings in the list, separated by the separator character, terminated
by the terminator character. The terminator character is not added if
drop_redundant_terminator is true and the last string already ends with
the terminator. */
extern char *string_list_join (const string_list_ty *slp, char separator,
char terminator, bool drop_redundant_terminator);
/* Return 1 if s is contained in the list of strings, 0 otherwise. */
extern bool string_list_member (const string_list_ty *slp, const char *s);
#ifdef __cplusplus
}
#endif
#endif /* _STR_LIST_H */
--- NEW FILE: Man.xs ---
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
//#include "ppport.h"
//#include "const-c.inc"
static char *current_font = NULL;
static char *previous_font = NULL;
static char *regular_font = NULL;
void set_font(char *font)
{
// fprintf(stderr, " set_font(%s)\n", font);
char *saved_previous;
if (current_font == NULL)
current_font = strdup("R");
if (previous_font == NULL)
previous_font = strdup("R");
saved_previous = previous_font;
previous_font = strdup(current_font);
if (font[0] == '\0')
{
free(current_font);
current_font = strdup("R");
}
else if (0 == strcmp(font, "P") ||
0 == strcmp(font, "[]") ||
0 == strcmp(font, "[P]"))
{
free(current_font);
current_font = strdup(saved_previous);
}
else if (strlen(font) == 1)
{
free(current_font);
current_font = strdup(font);
}
else if (strlen(font) == 2)
{
free(current_font);
current_font = malloc(4);
current_font[0] = '(';
current_font[1] = font[0];
current_font[2] = font[1];
current_font[3] = '\0';
}
else
{
fprintf(stderr, "not implemented");
}
// fprintf(stderr, "my set_font => r:'%s', p:'%s', c:'%s'\n", regular_font, previous_font, current_font);
free(saved_previous);
// fprintf(stderr, " end set_font()\n");
}
void set_regular(char *font)
{
// fprintf(stderr, " set_regular(%s)\n", font);
set_font(font);
free(regular_font);
regular_font = strdup(current_font);
// fprintf(stderr, " end set_regular()\n");
}
char *do_fonts(char *string, char *ref)
{
// fprintf(stderr, "do_fonts(%s)\n", string);
char *tmp;
char *pc = string;
char *pc_tmp;
char previous[10];
char current[10];
char new[10];
char last[10];
if (current_font == NULL)
current_font = strdup("R");
if (previous_font == NULL)
previous_font = strdup("R");
if (regular_font == NULL)
regular_font = strdup("R");
last[0] = '\0';
Newx(tmp, strlen(string)*2, char);
pc_tmp = tmp;
strcpy(previous, previous_font);
strcpy(current, current_font);
if (strcmp(regular_font, current_font) != 0)
strcpy(new, current_font);
else
new[0] = '\0';
while (*pc != '\0')
{
if (pc[0] == 'E' && pc[1] == '<' && pc[2] == '.')
{
if (new[0] != '\0')
{
char *pc_new = new;
while (*pc_new != '\0')
*pc_tmp++ = *pc_new++;
*pc_tmp++ = '<';
new[0] = '\0';
}
pc_tmp[0] = pc[0];
pc_tmp[1] = pc[1];
pc_tmp[2] = pc[2];
pc_tmp+=3;
pc+=3;
int count = 0;
while (*pc !='>' || count != 0)
{
if (*pc == '<')
count++;
if (*pc == '>')
count--;
*pc_tmp++ = *pc++;
}
}
else if (pc[0] == '\\' && pc[1] == 'f')
{
/* We found a font modifier */
char f[10];
pc += 2;
/* Extract the font */
if (*pc == '[')
{
char *pc_f = f;
pc++;
while(*pc != ']' && (pc_f - f < 10))
*pc_f++ = *pc++;
if (*pc != ']')
die("font too long: '%s%s'\n", f, pc);
pc++;
*pc_f = '\0';
}
else if (*pc == '(')
{
pc++;
f[0] = *pc++;
f[1] = *pc++;
f[2] = '\0';
}
else
{
f[0] = *pc++;
f[1] = '\0';
}
// fprintf(stderr, "found font: '%s'\n", f);
/* Canonize the font */
if (f[1] == '\0')
{
if (f[0] == '\0' || f[0] == 'P')
{
strcpy(f,previous);
}
else if (f[0] == '1')
f[0] = 'R';
else if (f[0] == '2')
f[0] = 'I';
else if (f[0] == '3')
f[0] = 'B';
else if (f[0] == '3')
{
f[0] = 'B';
f[1] = 'I';
f[2] = '\0';
}
}
// fprintf(stderr, "found font: '%s'\n", f);
/*
if ((pc[0] == 'P' && pc++) ||
(pc[0] == '[' && pc[1] == ']' && (pc = pc + 2)) ||
(pc[0] == '[' && pc[1] == 'P' && pc[2] == ']' && (pc = pc +3)))
{
if (0 == strcmp(previous, regular_font))
{
strcpy(previous, current);
new[0] = '>';
new[1] = '\0';
strcpy(current, regular_font);
}
else
{
strcpy(new, previous);
strcpy(previous, current);
strcpy(current, new);
}
}
else */
if (0 == strcmp(f, regular_font))
{
// printf(" regular\n");
strcpy(previous, current);
// if (0 != strcmp(current, regular_font))
// {
new[0] = '>';
new[1] = '\0';
strcpy(current, regular_font);
// }
}
else// if (pc[1] pc[0] == 'B' || pc[0] == 'I' || pc[0] == 'R')
{
strcpy(previous, current);
strcpy(current, f);
strcpy(new, current);
}/*
else
{
fprintf(stderr, "unrecognized font: '%s'\n", pc);
}*/
}
else
{
// printf("%p %p\n", pc_tmp, pc);
if (new[0] != '\0')
{
char *pc_new = new;
if (strcmp(new, last) != 0 && last[0] != '\0')
*pc_tmp++ = '>';
if (new[0] != '>')
{
if (strcmp(new, last) != 0)
{
while (*pc_new != '\0')
*pc_tmp++ = *pc_new++;
*pc_tmp++ = '<';
strcpy(last, new);
}
}
else
last[0] = '\0';
new[0] = '\0';
}
*pc_tmp++ = *pc++;
}
}
if (last[0] != '\0')
{
if (pc_tmp[-1] == '\n')
{
if (pc_tmp[-2] == '<')
{
if (pc_tmp[-3] == 'B' || pc_tmp[-3] == 'I' || pc_tmp[-3] == 'R')
{
pc_tmp -=3;
}
else if (pc_tmp[-3] == 'W' && pc_tmp[-4] == 'C')
{
pc_tmp -=4;
}
else
{
pc_tmp[-1] = '>';
}
}
else
{
pc_tmp[-1] = '>';
}
*pc_tmp++ = '\n';
}
else
*pc_tmp++ = '>';
}
*pc_tmp = '\0';
strcpy(previous_font, previous);
strcpy(current_font, current);
// fprintf(stderr, "end do_fonts: '%s'\n", tmp);
return tmp;
}
MODULE = Locale::Po4a::Man PACKAGE = Locale::Po4a::Man
char *
do_fonts(string, ref)
char * string
char * ref
void set_regular(font)
char * font
void set_font(font)
char * font
--- NEW FILE: TransTractor.xs ---
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
//#include "ppport.h"
//#include "const-c.inc"
char *TransTractor_write(SV* self, char *filename)
{
FILE *out = NULL;
if (NULL == filename)
croak("Can't write to a file without filename");
if (0 == strcmp(filename, "-"))
{
out = stdout;
}
else
{
int count;
I32 i = 0;
dSP;
ENTER;
out = fopen(filename, "w");
if (NULL == out)
{
perror("fopen");
croak("Can't create %s.\n", filename);
}
PUSHMARK(SP);
XPUSHs(self);
PUTBACK;
count = call_method("docheader", G_ARRAY);
SPAGAIN;
for (i=0; i< count; i++)
{
fputs(POPp, out);
}
HV *hv = SvRV(self);
// if (hv_exists(hv, "TT", 2))
// {
SV **psv = hv_fetch(hv, "TT", 2,0);
if (NULL != psv)
{
SV *sv = *psv;
// if (hv_exists(SvRV(sv), "doc_out", 7))
// {
psv = hv_fetch(SvRV(sv), "doc_out", 7, 0);
sv = *psv;
AV *av = SvRV(sv);
for (i = 0; i < av_len(av); i++)
{
fputs(SvRV(*av_fetch(av, i, 0)), out);
}
// }
// else
// {
// croak("No doc_out.\n");
// }
}
// }
// else
// {
// croak("No TT.\n");
// }
fclose(out);
PUTBACK;
LEAVE;
}
}
MODULE = Locale::Po4a::TransTractor PACKAGE = Locale::Po4a::TransTractor PREFIX = TransTractor_
void TransTractor_write(self, filename)
SV * self
char * filename
--- NEW FILE: Po.h ---
#ifndef _PO_H
#define _PO_H
#include <gettext-po.h>
#include "message.h"
extern void textmode_xerror (int severity,
po_message_t message,
const char *filename, size_t lineno, size_t column, int multiline_p, const char *message_text);
extern void textmode_xerror2 (int severity,
po_message_t message1,
const char *filename1, size_t lineno1, size_t column1,
int multiline_p1, const char *message_text1,
po_message_t message2,
const char *filename2, size_t lineno2, size_t column2,
int multiline_p2, const char *message_text2);
struct po_xerror_handler default_xerror_handler={textmode_xerror,
textmode_xerror2};
struct Po {
// po_file_t po_file;
message_list_ty *mlp;
};
typedef struct Po Locale__Po4a__Po;
typedef struct Po * Locale_Po4a_Po;
#endif
- Previous message: [Po4a-commits] "po4a/extension Build.PL,NONE,1.1 typemap,NONE,1.1"
- Next message: [Po4a-commits] "po4a/lib/Locale/Po4a Man.pm, 1.196, 1.197 Po.pm,
1.72, 1.73 TransTractor.pm, 1.90, 1.91"
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Po4a-commits
mailing list