import os import sys # The runtime environment assumes ISO8859/1 (European including Spain) # CH, LL, and RR are not supported glyphs so we handle them here using 2 letters # Note that when compiled as a stand-alone .exe under DOS/Windows, # the default DOS character set is *not* ISO8859/1 and therefore the # accented characters will not be displayed correctly. # Customise here: TITLE = "Juez Lingüístico FISE" Version = "2.0" ENTER_WORD = "Teclee la palabra por la que desea consultar" SUBMIT = "Consultar" GOOD_WORD = "PALABRA ACEPTADA" BAD_WORD = "PALABRA NO ACEPTADA" INVALID_ENTRY = "Caracteres no válidos" WRONG_SIZE = "La palabra consultada debe tener entre dos y quince fichas" NO_ARG_GIVEN = "(vacio)" WORD = "palabra" PROGNAME = "juez2.cgi" static showroot = (0==0) #include "FISE/FISE-ROOT.h" # directory is protected. File is not available for download LATIN_CAPITAL_LETTER_N_WITH_TILDE = 0xD1 LATIN_SMALL_LETTER_N_WITH_TILDE = 0xF1 LATIN_SMALL_LETTER_A_WITH_ACUTE = 0xE1 LATIN_SMALL_LETTER_E_WITH_ACUTE = 0xE9 LATIN_SMALL_LETTER_I_WITH_ACUTE = 0xED LATIN_SMALL_LETTER_O_WITH_ACUTE = 0xF3 LATIN_SMALL_LETTER_U_WITH_ACUTE = 0xFA LATIN_SMALL_LETTER_U_WITH_DIAERESIS = 0xFC LATIN_SMALL_LETTER_E_WITH_GRAVE = 0xE8 LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX = 0xEE LATIN_CAPITAL_LETTER_A_WITH_ACUTE = 0xC1 LATIN_CAPITAL_LETTER_E_WITH_ACUTE = 0xC9 LATIN_CAPITAL_LETTER_I_WITH_ACUTE = 0xCD LATIN_CAPITAL_LETTER_O_WITH_ACUTE = 0xD3 LATIN_CAPITAL_LETTER_U_WITH_ACUTE = 0xDA LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS = 0xDC LATIN_CAPITAL_LETTER_E_WITH_GRAVE = 0xC8 LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX = 0xCE # # Web param stuff derived directly from code by Harry H. Cheng, 11/24/1995 * # unescapechar(url) { from = url; to = from hex[3]; hexp=hex # contains xx of %xx while True: c = *from += 1 if c == '+': c = ' ' if c == '%': *hexp++ = *from += 1; *hexp++ = *from += 1; *hexp = '\0' c = strtol(hex, NULL, 16); hexp = hex *to++ = c if c == '\0': return def getpairs(name, value): { # content length num=1 if (not strcmp("POST", os.getenv("REQUEST_METHOD"))) { # POST if ((cl = int(os.getenv("CONTENT_LENGTH"))) == 0) return 0 if (clientinput = () malloc(sizeof(char) * (cl+1))) == NULL: return -2 fgets(clientinput, cl+1, stdin) # get the client input else: # GET if ((qs = os.getenv("QUERY_STRING")) == NULL) return 0; else: cl = len(qs) if (clientinput = () malloc(sizeof(char) * (cl+1))) == NULL: return -2 clientinput = qs token = strchr(clientinput, '&') # & is the name/value pair separator while token != NULL: token = strchr(++token, '&') num += 1 # obtain the total number of pairs nam = () malloc(sizeof()*num) val = () malloc(sizeof()*num) if nam == NULL or val == NULL: return -2 for (i = 0, token = strtok(clientinput, "&"); token != NULL; i++) { l1 = len(token); l2 = strcspn(token,"=") nam[i] = () malloc(sizeof(char) * (l2+1)) if nam[i] == NULL: return -2 strncpy(nam[i], token, l2) nam[i][l2] = '\0' unescapechar(nam[i]) if l1 != l2+1: # name=value& val[i] = ()malloc(sizeof(char) * (l1-l2)) if val[i] == NULL: return -2 strcpy(val[i], token+l2+1) unescapechar(val[i]) else: val[i] = NULL # special case of name=& token = strtok(NULL, "&") free(clientinput) *name = nam; *value = val return num # return the number of entries # # Dictionary lookup code. See also 'token.c' * # typedef NODE ROOT_NODE = 1 # Root of dag V_END_OF_WORD = 23 # Bit number of W M_END_OF_WORD = (1L << V_END_OF_WORD) V_END_OF_NODE = 22 # Bit number of N M_END_OF_NODE = (1L << V_END_OF_NODE) V_LETTER = 24 M_LETTER = 0xFF M_NODE_POINTER = 0x1FFFFFL # Bit mask for node pointer typedef INDEX MAX_WORD_LEN = 128 def dawg_pr(NODE *dawg, INDEX node, len): static word[MAX_WORD_LEN] NODE *edge for (edge = (NODE *)&dawg[node]; ; edge++) { c = *edge # Don't rewrite this - its avoiding a MSC bug c = c >> V_LETTER c = c & M_LETTER word[len] = (char)c if (*edge & M_END_OF_WORD) != 0: word[len+1] = '\0' s = word while True: if (s == NULL) or (*s == '\0'): break ws = s s = strchr(ws, ';') if s != NULL: *s++ = '\0' ws2 = ws s2 = strchr(ws2, ' ') if s2 != NULL: *s2 = '\0' fprintf(stdout, "%s \n" % (ws2, ws)) fprintf(stdout, "
") c = *edge & M_NODE_POINTER if (*edge & M_NODE_POINTER) != 0: dawg_pr (dawg, c, len + 1) if (*edge & M_END_OF_NODE) != 0: break # End of node def dawg_print(NODE *dawg, INDEX node): if not showroot: return fprintf(stdout, "La palabra proviene de:
") dawg_pr(dawg, node, 0) fprintf(stdout, "
") def dawg_checkeq(NODE *dict, unsigned word): NODE *edge = dict+ROOT_NODE if edge == dict) return(0!=0: while True: ch = (int)(((*edge >> V_LETTER) & M_LETTER)) ch = ch&255 if ch == '=': if *word == '\0': dawg_print(dict, (*edge & M_NODE_POINTER)) return(0==0) if ch == *word: word += 1 if (edge = dict+(*edge & M_NODE_POINTER)) == dict: break # End of dict continue # edge moved down a level if ((*edge++) & M_END_OF_NODE) != 0: break # End of options return(0!=0) # Support for typographical conventions used (see document entitled 'COMMENT') static convert[256] # canonicalize ISO Latin1 GOOD = (0==0) BAD = (0!=0) def reformat(tiles): static word[32] wordp = word while True: c = *tiles += 1 if c == '4': c = LATIN_SMALL_LETTER_N_WITH_TILDE *wordp = c; if c == '\0': return word if c == '1': *wordp++ = 'c'; *wordp = 'h';} elif c == '2': *wordp++ = 'l'; *wordp = 'l';} elif c == '3': *wordp++ = 'r'; *wordp = 'r';} wordp += 1 def standardize(inword, outword): unsigned c while True: c = (unsigned int) (*inword++) & 255U if c == '\0': break c = convert[c] # remove accents, convert to lower, leave # tilde on n. if c == '?') return (BAD) if (c == 'c') and (convert[(unsigned int) (*inword) & 255U] == 'h'): # ch c = '1'; inword += 1 } elif (c == 'l') and (convert[(unsigned int) (*inword) & 255U] == 'l'): # ll c = '2'; inword += 1 } elif (c == 'r') and (convert[(unsigned int) (*inword) & 255U] == 'r'): # rr c = '3'; inword += 1 *outword++ = (char) c *outword = '\0' return (GOOD) def main(argc, argv): word = ( '\0' ) for i in range(0, 256): convert[i] = '?' # rejected unless explicitly specified for i in range('a', 'z'+1): convert[i] = i for i in range('A', 'Z'+1): convert[i] = tolower (i) # K and W not present in Spanish Scrabble convert['k'] = '?'; convert['w'] = '?' convert['K'] = '?'; convert['W'] = '?' # capital tilde N => lower tilde n, encoded here in 7-bit ascii as '4' # because the dawg code may not be 8-bit clean (signed char problem? - debug later...) convert[LATIN_CAPITAL_LETTER_N_WITH_TILDE] = '4' convert[LATIN_SMALL_LETTER_N_WITH_TILDE] = '4' # remove all accents and convert to lowercase convert[LATIN_SMALL_LETTER_A_WITH_ACUTE] = 'a' convert[LATIN_SMALL_LETTER_E_WITH_ACUTE] = 'e' convert[LATIN_SMALL_LETTER_I_WITH_ACUTE] = 'i' convert[LATIN_SMALL_LETTER_O_WITH_ACUTE] = 'o' convert[LATIN_SMALL_LETTER_U_WITH_ACUTE] = 'u' convert[LATIN_SMALL_LETTER_U_WITH_DIAERESIS] = 'u' convert[LATIN_SMALL_LETTER_E_WITH_GRAVE] = 'e' convert[LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX] = 'i' convert[LATIN_CAPITAL_LETTER_A_WITH_ACUTE] = 'a' convert[LATIN_CAPITAL_LETTER_E_WITH_ACUTE] = 'e' convert[LATIN_CAPITAL_LETTER_I_WITH_ACUTE] = 'i' convert[LATIN_CAPITAL_LETTER_O_WITH_ACUTE] = 'o' convert[LATIN_CAPITAL_LETTER_U_WITH_ACUTE] = 'u' convert[LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS] = 'u' convert[LATIN_CAPITAL_LETTER_E_WITH_GRAVE] = 'e' convert[LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX] = 'i' { # WEB static s, line[32] c = 0 if (getenv ("REQUEST_METHOD") != NULL) { # Invoked from CGI pairs = 0 # WEB fprintf(stdout, "Content-type: text/html\r\n") fprintf(stdout, "\r\n") fprintf(stdout, "\r\n") fprintf(stdout, "\r\n") fprintf(stdout, "\r\n") fprintf(stdout, "\r\n") fprintf(stdout, "\r\n") fprintf(stdout, "%s %s\r\n" % (TITLE, Version)) fprintf(stdout, "\r\n") fprintf(stdout, "\r\n") fprintf(stdout, "\r\n") fprintf(stdout, "

%s %s

\r\n" % (TITLE, Version)) # display form for user to enter word fprintf(stdout, "
\r\n" % (PROGNAME)) fprintf(stdout, "%s: \r\n" % (ENTER_WORD)) fprintf(stdout, "\r\n" % (WORD)) fprintf(stdout, "\r\n" % (SUBMIT)) fprintf(stdout, "
\r\n") fprintf(stdout, "
¿Mostrar la palabra origen? ") if (strcmp(os.getenv("REQUEST_METHOD"), "POST") == 0) pairs = getpairs(&name, &value) if pairs > 0: for i in range(0, pairs): if (strcmp(name[i], "showroot") == 0) {showroot = (*value[i] == 'Y'); break;} fprintf(stdout, " SI" % (showroot ? " checked" : "") fprintf(stdout, " NO
\r\n" % (showroot ? "" : " checked") fprintf(stdout, "
\r\n") if (strcmp(os.getenv("REQUEST_METHOD"), "POST") == 0) { GIVEN_ARG = NULL # word supplied, check it if pairs > 0: # TO DO: conversions into and out of quoted web format; hex entity refs for accented chars for i in range(0, pairs): if strcmp(name[i], WORD) == 0:GIVEN_ARG = value[i]; break;} for i in range(0, pairs): if (strcmp(name[i], "showroot") == 0) {showroot = *value[i] == 'Y'; break;} if (GIVEN_ARG != NULL) and (not standardize (GIVEN_ARG, word)): fprintf(stdout, "%s: %s\n\n" % (INVALID_ENTRY, GIVEN_ARG)) } elif (GIVEN_ARG == NULL) or (strlen (GIVEN_ARG) > 30) or (strlen (word) < 2) or (strlen (word) > 15): fprintf(stdout, "%s: %s\n" % (WRONG_SIZE, (GIVEN_ARG == NULL ? NO_ARG_GIVEN : GIVEN_ARG))) else: if dawg_checkeq(_token, word): fprintf(stdout, "%s: %s\n" % (GOOD_WORD, reformat(word))) else: fprintf(stdout, "%s: %s\n" % (BAD_WORD, reformat(word))) for i in range(pairs): if name[i] != NULL) free(name[i]: if value[i] != NULL) free(value[i]: if name != NULL) free(name: if value != NULL) free(value: else: fprintf(stdout, "Form does not seem to include the required field '%s'.\r\n" % (WORD)) fprintf(stdout, "\r\n") fprintf(stdout, "\r\n") exit (0)