Blame gimatria.c

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
}