|
Packit |
ca9683 |
/* Copyright (C) 2003 Nadav Har'El and Dan Kenigsberg */
|
|
Packit |
ca9683 |
|
|
Packit |
ca9683 |
#include <stdio.h>
|
|
Packit |
ca9683 |
#include <string.h>
|
|
Packit |
ca9683 |
|
|
Packit |
ca9683 |
#include "hspell.h"
|
|
Packit |
ca9683 |
|
|
Packit |
ca9683 |
extern int hspell_debug;
|
|
Packit |
ca9683 |
|
|
Packit |
ca9683 |
/* functions for checking valid gimatria */
|
|
Packit |
ca9683 |
static unsigned int
|
|
Packit |
ca9683 |
gim2int(const char *w){
|
|
Packit |
ca9683 |
int n=0;
|
|
Packit |
ca9683 |
if(hspell_debug) fprintf(stderr,"gim2int got %s ",w);
|
|
Packit |
ca9683 |
while(*w){
|
|
Packit |
ca9683 |
switch(*w){
|
|
Packit |
ca9683 |
case '\'':
|
|
Packit |
ca9683 |
/* ad-hoc change: ג' can mean with 3 or 3000. Our
|
|
Packit |
ca9683 |
* check that the ' is not in the end forces to be 3,
|
|
Packit |
ca9683 |
* because I don't want to recognize stuff like תריג'
|
|
Packit |
ca9683 |
* = 613,000.
|
|
Packit |
ca9683 |
* TODO: consider if I should remove this if(w[1])
|
|
Packit |
ca9683 |
* line.
|
|
Packit |
ca9683 |
* */
|
|
Packit |
ca9683 |
if(w[1])
|
|
Packit |
ca9683 |
n*=1000;
|
|
Packit |
ca9683 |
break;
|
|
Packit |
ca9683 |
case 'א': n+=1; break;
|
|
Packit |
ca9683 |
case 'ב': n+=2; break;
|
|
Packit |
ca9683 |
case 'ג': n+=3; break;
|
|
Packit |
ca9683 |
case 'ד': n+=4; break;
|
|
Packit |
ca9683 |
case 'ה': n+=5; break;
|
|
Packit |
ca9683 |
case 'ו': n+=6; break;
|
|
Packit |
ca9683 |
case 'ז': n+=7; break;
|
|
Packit |
ca9683 |
case 'ח': n+=8; break;
|
|
Packit |
ca9683 |
case 'ט': n+=9; break;
|
|
Packit |
ca9683 |
case 'י': n+=10; break;
|
|
Packit |
ca9683 |
case 'כ': case 'ך': n+=20; break;
|
|
Packit |
ca9683 |
case 'ל': n+=30; break;
|
|
Packit |
ca9683 |
case 'מ': case 'ם': n+=40; break;
|
|
Packit |
ca9683 |
case 'נ': case 'ן': n+=50; break;
|
|
Packit |
ca9683 |
case 'ס': n+=60; break;
|
|
Packit |
ca9683 |
case 'ע': n+=70; break;
|
|
Packit |
ca9683 |
case 'פ': case 'ף': n+=80; break;
|
|
Packit |
ca9683 |
case 'צ': case 'ץ': n+=90; break;
|
|
Packit |
ca9683 |
case 'ק': n+=100; break;
|
|
Packit |
ca9683 |
case 'ר': n+=200; break;
|
|
Packit |
ca9683 |
case 'ש': n+=300; break;
|
|
Packit |
ca9683 |
case 'ת': n+=400; break;
|
|
Packit |
ca9683 |
/* ignore " characters */
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
w++;
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
if(hspell_debug) fprintf(stderr,"returning %d\n",n);
|
|
Packit |
ca9683 |
return n;
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
#if 0
|
|
Packit |
ca9683 |
void
|
|
Packit |
ca9683 |
int2gim(int n, char *buf, int sizebuf)
|
|
Packit |
ca9683 |
{
|
|
Packit |
ca9683 |
int i;
|
|
Packit |
ca9683 |
int nn, divisor;
|
|
Packit |
ca9683 |
if(n<=0){
|
|
Packit |
ca9683 |
/* no gimatria... */
|
|
Packit |
ca9683 |
if(sizebuf) buf[0]='\0';
|
|
Packit |
ca9683 |
return;
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
if(n>=1000*1000*1000) divisor=1000*1000*1000;
|
|
Packit |
ca9683 |
else if(n>=1000*1000) divisor=1000*1000;
|
|
Packit |
ca9683 |
else if(n>=1000) divisor=1000;
|
|
Packit |
ca9683 |
else divisor=1;
|
|
Packit |
ca9683 |
|
|
Packit |
ca9683 |
#define out1(c) {if(i
|
|
Packit |
ca9683 |
|
|
Packit |
ca9683 |
while(divisor){
|
|
Packit |
ca9683 |
nn=n/divisor;
|
|
Packit |
ca9683 |
#define check(
|
|
Packit |
ca9683 |
DO HERE THE NORMAL CODE FOR nn
|
|
Packit |
ca9683 |
n-=nn*divisor;
|
|
Packit |
ca9683 |
divisor/=1000;
|
|
Packit |
ca9683 |
if(divisor)
|
|
Packit |
ca9683 |
out1('\'');
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
buf[i]='\0';
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
#endif
|
|
Packit |
ca9683 |
/* print Hebrew numerals. The output string must be big enough to store
|
|
Packit |
ca9683 |
the resulting hebrew number (30 characters is more then enough)!
|
|
Packit |
ca9683 |
*/
|
|
Packit |
ca9683 |
/* appendStr appends the src string at the given dst pointer, and return
|
|
Packit |
ca9683 |
a pointer to the end of the resulting string (after the original dst
|
|
Packit |
ca9683 |
string). Note that a null is appended to the resulting string, and the
|
|
Packit |
ca9683 |
returned pointer is actually a pointer to it.
|
|
Packit |
ca9683 |
*/
|
|
Packit |
ca9683 |
static char *
|
|
Packit |
ca9683 |
appendStr(src,dst)
|
|
Packit |
ca9683 |
char *src,*dst;
|
|
Packit |
ca9683 |
{
|
|
Packit |
ca9683 |
while(*src){
|
|
Packit |
ca9683 |
*(dst++)=*(src++);
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
*dst='\0';
|
|
Packit |
ca9683 |
return dst;
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
static void
|
|
Packit |
ca9683 |
int2gim(unsigned int n, char *buf)
|
|
Packit |
ca9683 |
{
|
|
Packit |
ca9683 |
static char *digits[3][9] = {
|
|
Packit |
ca9683 |
{"א","ב","ג","ד","ה","ו","ז","ח","ט"},
|
|
Packit |
ca9683 |
{"י","כ","ל","מ","נ","ס","ע","פ","צ"},
|
|
Packit |
ca9683 |
{"ק","ר","ש","ת","קת","רת","שת","תת","קתת"}
|
|
Packit |
ca9683 |
};
|
|
Packit |
ca9683 |
static char *special[2] = {"וט","זט"};
|
|
Packit |
ca9683 |
int i = 0;
|
|
Packit |
ca9683 |
char *b=buf, *bleft, *bright;
|
|
Packit |
ca9683 |
*b='\0';
|
|
Packit |
ca9683 |
|
|
Packit |
ca9683 |
if(hspell_debug) fprintf(stderr,"int2gim got %d ",n);
|
|
Packit |
ca9683 |
while (n>0) {
|
|
Packit |
ca9683 |
if (i == 3) {i = 0; b=appendStr("\'", b);}
|
|
Packit |
ca9683 |
if (!i && (n%100 == 15 || n%100 == 16)) {
|
|
Packit |
ca9683 |
b=appendStr(special[n%100 - 15],b);
|
|
Packit |
ca9683 |
n /= 100;
|
|
Packit |
ca9683 |
i = 2;
|
|
Packit |
ca9683 |
} else {
|
|
Packit |
ca9683 |
if (n%10) b=appendStr(digits[i][n%10 - 1],
|
|
Packit |
ca9683 |
b);
|
|
Packit |
ca9683 |
n /= 10;
|
|
Packit |
ca9683 |
i++;
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
/* reverse the string */
|
|
Packit |
ca9683 |
if(hspell_debug) fprintf(stderr,"before %s\n",buf);
|
|
Packit |
ca9683 |
if(buf[0]!='\0')
|
|
Packit |
ca9683 |
for(bleft=buf, bright=b-1; bright>bleft; bleft++, bright--){
|
|
Packit |
ca9683 |
char tmp;
|
|
Packit |
ca9683 |
tmp=*bleft;
|
|
Packit |
ca9683 |
*bleft=*bright;
|
|
Packit |
ca9683 |
*bright=tmp;
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
if(hspell_debug) fprintf(stderr,"after %s\n",buf);
|
|
Packit |
ca9683 |
/* we decided gimatria to end in final letters */
|
|
Packit |
ca9683 |
if(buf[0]){
|
|
Packit |
ca9683 |
switch(b[-1]){
|
|
Packit |
ca9683 |
case 'כ': b[-1]='ך'; break;
|
|
Packit |
ca9683 |
case 'מ': b[-1]='ם'; break;
|
|
Packit |
ca9683 |
case 'נ': b[-1]='ן'; break;
|
|
Packit |
ca9683 |
case 'צ': b[-1]='ץ'; break;
|
|
Packit |
ca9683 |
case 'פ': b[-1]='ף'; break;
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
|
|
Packit |
ca9683 |
/* if just one letter was output, follow it by '; Otherwise, put
|
|
Packit |
ca9683 |
* a " before the last letter */
|
|
Packit |
ca9683 |
if(buf[0]!='\0') {
|
|
Packit |
ca9683 |
if(buf[1]=='\0'){
|
|
Packit |
ca9683 |
buf[1]='\'';
|
|
Packit |
ca9683 |
buf[2]='\0';
|
|
Packit |
ca9683 |
/* NOTE: this test is to make 5001 was ה'א', not ה'א.
|
|
Packit |
ca9683 |
* I'm not sure this is warranted, but it's what we had in
|
|
Packit |
ca9683 |
* hspell.pl. Note that b[-2] exists because of the previous
|
|
Packit |
ca9683 |
* test. */
|
|
Packit |
ca9683 |
} else if(b[-2]=='\'' && b[-1]!='\'') {
|
|
Packit |
ca9683 |
b[0]='\'';
|
|
Packit |
ca9683 |
b[1]='\0';
|
|
Packit |
ca9683 |
} else if(b[-1]!='\'') { /* no " in ה' */
|
|
Packit |
ca9683 |
char save=b[-1];
|
|
Packit |
ca9683 |
b[-1]='"';
|
|
Packit |
ca9683 |
b[0]=save;
|
|
Packit |
ca9683 |
b[1]='\0';
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
if(hspell_debug) fprintf(stderr,"returning %s\n",buf);
|
|
Packit |
ca9683 |
}
|
|
Packit |
ca9683 |
/* TODO: stuff like טו' is now recognized as 15,000. In hspell.pl this
|
|
Packit |
ca9683 |
* wasn't recognized because (I think) a bug in int2gim which generate
|
|
Packit |
ca9683 |
* something like טו"'. Frankly, I doubt we want to recognize this case
|
|
Packit |
ca9683 |
* at all... */
|
|
Packit |
ca9683 |
unsigned int
|
|
Packit |
ca9683 |
hspell_is_canonic_gimatria(const char *w)
|
|
Packit |
ca9683 |
{
|
|
Packit |
ca9683 |
const char *p;
|
|
Packit |
ca9683 |
char buf[50];
|
|
Packit |
ca9683 |
unsigned int val;
|
|
Packit |
ca9683 |
/* make a quick look for quotes (if there are none, this is no
|
|
Packit |
ca9683 |
* gimatria and we return 0 */
|
|
Packit |
ca9683 |
for(p=w; *p && *p!='"' && *p!='\''; p++)
|
|
Packit |
ca9683 |
;
|
|
Packit |
ca9683 |
if(!*p)
|
|
Packit |
ca9683 |
return 0;
|
|
Packit |
ca9683 |
/* Now make the actual test for canonic gimatria */
|
|
Packit |
ca9683 |
int2gim((val=gim2int(w)), buf);
|
|
Packit |
ca9683 |
if(strcmp(w, buf)) val=0;
|
|
Packit |
ca9683 |
return val;
|
|
Packit |
ca9683 |
}
|