/* Copyright (C) 2003 Nadav Har'El and Dan Kenigsberg */
#include <stdio.h>
#include <string.h>
#include "hspell.h"
extern int hspell_debug;
/* functions for checking valid gimatria */
static int
gim2int(const char *w){
int n=0;
if(hspell_debug) fprintf(stderr,"gim2int got %s ",w);
while(*w){
switch(*w){
case '\'':
/* ad-hoc change: â' can mean with 3 or 3000. Our
* check that the ' is not in the end forces to be 3,
* because I don't want to recognize stuff like úøéâ'
* = 613,000.
* TODO: consider if I should remove this if(w[1])
* line.
* */
if(w[1])
n*=1000;
break;
case 'à': n+=1; break;
case 'á': n+=2; break;
case 'â': n+=3; break;
case 'ã': n+=4; break;
case 'ä': n+=5; break;
case 'å': n+=6; break;
case 'æ': n+=7; break;
case 'ç': n+=8; break;
case 'è': n+=9; break;
case 'é': n+=10; break;
case 'ë': case 'ê': n+=20; break;
case 'ì': n+=30; break;
case 'î': case 'í': n+=40; break;
case 'ð': case 'ï': n+=50; break;
case 'ñ': n+=60; break;
case 'ò': n+=70; break;
case 'ô': case 'ó': n+=80; break;
case 'ö': case 'õ': n+=90; break;
case '÷': n+=100; break;
case 'ø': n+=200; break;
case 'ù': n+=300; break;
case 'ú': n+=400; break;
/* ignore " characters */
}
w++;
}
if(hspell_debug) fprintf(stderr,"returning %d\n",n);
return n;
}
#if 0
void
int2gim(int n, char *buf, int sizebuf)
{
int i;
int nn, divisor;
if(n<=0){
/* no gimatria... */
if(sizebuf) buf[0]='\0';
return;
}
if(n>=1000*1000*1000) divisor=1000*1000*1000;
else if(n>=1000*1000) divisor=1000*1000;
else if(n>=1000) divisor=1000;
else divisor=1;
#define out1(c) {if(i<sizebuf-1){ buf[i++]=(c); }}
while(divisor){
nn=n/divisor;
#define check(
DO HERE THE NORMAL CODE FOR nn
n-=nn*divisor;
divisor/=1000;
if(divisor)
out1('\'');
}
buf[i]='\0';
}
#endif
/* print Hebrew numerals. The output string must be big enough to store
the resulting hebrew number (30 characters is more then enough)!
*/
/* appendStr appends the src string at the given dst pointer, and return
a pointer to the end of the resulting string (after the original dst
string). Note that a null is appended to the resulting string, and the
returned pointer is actually a pointer to it.
*/
static char *
appendStr(src,dst)
char *src,*dst;
{
while(*src){
*(dst++)=*(src++);
}
*dst='\0';
return dst;
}
static void
int2gim(int n, char *buf)
{
static char *digits[3][9] = {
{"à","á","â","ã","ä","å","æ","ç","è"},
{"é","ë","ì","î","ð","ñ","ò","ô","ö"},
{"÷","ø","ù","ú","÷ú","øú","ùú","úú","÷úú"}
};
static char *special[2] = {"åè","æè"};
int i = 0;
char *b=buf, *bleft, *bright;
*b='\0';
if(hspell_debug) fprintf(stderr,"int2gim got %d ",n);
while (n>0) {
if (i == 3) {i = 0; b=appendStr("\'", b);}
if (!i && (n%100 == 15 || n%100 == 16)) {
b=appendStr(special[n%100 - 15],b);
n /= 100;
i = 2;
} else {
if (n%10) b=appendStr(digits[i][n%10 - 1],
b);
n /= 10;
i++;
}
}
/* reverse the string */
if(hspell_debug) fprintf(stderr,"before %s\n",buf);
if(buf[0]!='\0')
for(bleft=buf, bright=b-1; bright>bleft; bleft++, bright--){
char tmp;
tmp=*bleft;
*bleft=*bright;
*bright=tmp;
}
if(hspell_debug) fprintf(stderr,"after %s\n",buf);
/* we decided gimatria to end in final letters */
if(buf[0]){
switch(b[-1]){
case 'ë': b[-1]='ê'; break;
case 'î': b[-1]='í'; break;
case 'ð': b[-1]='ï'; break;
case 'ö': b[-1]='õ'; break;
case 'ô': b[-1]='ó'; break;
}
}
/* if just one letter was output, follow it by '; Otherwise, put
* a " before the last letter */
if(buf[0]!='\0') {
if(buf[1]=='\0'){
buf[1]='\'';
buf[2]='\0';
/* NOTE: this test is to make 5001 was ä'à', not ä'à.
* I'm not sure this is warrented, but it's what we had in
* hspell.pl. Note that b[-2] exists because of the previous
* test. */
} else if(b[-2]=='\'' && b[-1]!='\'') {
b[0]='\'';
b[1]='\0';
} else if(b[-1]!='\'') { /* no " in ä' */
char save=b[-1];
b[-1]='"';
b[0]=save;
b[1]='\0';
}
}
if(hspell_debug) fprintf(stderr,"returning %s\n",buf);
}
/* TODO: stuff like èå' is now recognized as 15,000. In hspell.pl this
* wasn't recognized because (I think) a bug in int2gim which generate
* something like èå"'. Frankly, I doubt we want to recognize this case
* at all... */
int
hspell_is_canonic_gimatria(const char *w)
{
const char *p;
char buf[50];
int val;
/* make a quick look for quotes (if there are none, this is no
* gimatria and we return 0 */
for(p=w; *p && *p!='"' && *p!='\''; p++)
;
if(!*p)
return 0;
/* Now make the actual test for canonic gimatria */
int2gim((val=gim2int(w)), buf);
if(strcmp(w, buf)) val=0;
return val;
}
syntax highlighted by Code2HTML, v. 0.9.1