1 /* Hey EMACS -*- linux-c -*- */
2 /* $Id$ */
3 
4 /*  libticonv - charset library, a part of the TiLP project
5  *  Copyright (C) 2006-2006 Romain Lievin and Kevin Kofler
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software Foundation,
19  *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /*
23 	This unit contains raw varname to TI-charset conversion routines.
24 
25 	The detokenization is used to translate some raw varnames into TI-charset
26 	encoded varnames. Tokenization is the reverse way.
27 	Many functions depends on the calculator model and the variable type ID.
28 
29 	This is needed for the following calcs: 73/82/83/83+/84+.
30 */
31 
32 #ifdef HAVE_CONFIG_H
33 #  include <config.h>
34 #endif
35 
36 #include <stdio.h>
37 #include <string.h>
38 #include <glib.h>
39 
40 #include "ticonv.h"
41 
42 //---
43 
44 #define MAXCHARS	((8+1+8+1) * 4)
45 
46 //---
47 
detokenize_vartype(CalcModel model,const char * src,unsigned char type)48 static char *detokenize_vartype(CalcModel model, const char *src, unsigned char type)
49 {
50 	char *dst;
51 
52 	switch(model)
53 	{
54 	case CALC_TI73:
55 		if (type == 0x0F)
56 		{
57 			return (dst = g_strdup("Window"));
58 		}
59 		if (type == 0x11)
60 		{
61 			return (dst = g_strdup("TblSet"));
62 		}
63 		break;
64 	case CALC_TI82:
65 		if (type == 0x0B)
66 		{
67 			return (dst = g_strdup("Window"));
68 		}
69 		if (type == 0x0C)
70 		{
71 			return (dst = g_strdup("RclWin"));
72 		}
73 		if (type == 0x0D)
74 		{
75 			return (dst = g_strdup("TblSet"));
76 		}
77 		break;
78 	case CALC_TI83:
79 	case CALC_TI83P:
80 	case CALC_TI84P:
81 	case CALC_TI84PC:
82 	case CALC_TI84P_USB:
83 	case CALC_TI84PC_USB:
84 	case CALC_TI83PCE_USB:
85 	case CALC_TI84PCE_USB:
86 	case CALC_TI82A_USB:
87 	case CALC_TI84PT_USB:
88 		if (type == 0x0F)
89 		{
90 			return (dst = g_strdup("Window"));
91 		}
92 		if (type == 0x10)
93 		{
94 			return (dst = g_strdup("RclWin"));
95 		}
96 		if (type == 0x11)
97 		{
98 			return (dst = g_strdup("TblSet"));
99 		}
100 		break;
101 	case CALC_TI85:
102 	case CALC_TI86:
103 		if (type == 0x17)
104 		{
105 			return (dst = g_strdup("Func"));
106 		}
107 		if (type == 0x18)
108 		{
109 			return (dst = g_strdup("Pol"));
110 		}
111 		if (type == 0x19)
112 		{
113 			return (dst = g_strdup("Param"));
114 		}
115 		if (type == 0x1A)
116 		{
117 			return (dst = g_strdup("DifEq"));
118 		}
119 		if (type == 0x1B)
120 		{
121 			return (dst = g_strdup("ZRCL"));
122 		}
123 		break;
124 	default:
125 		break;
126 	}
127 
128 	return NULL;
129 }
130 
131 // beware: raw varname is not always NUL-terminated
detokenize_varname(CalcModel model,const char * src,unsigned char type)132 static char *detokenize_varname(CalcModel model, const char *src, unsigned char type)
133 {
134 	int i;
135 	unsigned int tok1 = src[0] & 0xff;
136 	unsigned int tok2 = src[1] & 0xff;
137 	char *dst;
138 
139 	switch (tok1)
140 	{
141 	case 0x3C:			/* Image: Image1 to Image0 */
142 		if (type == 0x1A)
143 		{
144 			if (tok2 != 0x09)
145 			{
146 				dst = g_strdup_printf("Image%d", tok2 + 1);
147 			}
148 			else
149 			{
150 				dst = g_strdup("Image0");
151 			}
152 		}
153 		else
154 		{
155 			dst = g_strndup(src, 8);
156 		}
157 		break;
158 
159 	case 0x5C:			/* Matrix: [A] to [E] or [J] */
160 		switch(tok2)
161 		{
162 		case 0x00: dst = g_strdup_printf("%cA]", '\xc1'); break;
163 		case 0x01: dst = g_strdup_printf("%cB]", '\xc1'); break;
164 		case 0x02: dst = g_strdup_printf("%cC]", '\xc1'); break;
165 		case 0x03: dst = g_strdup_printf("%cD]", '\xc1'); break;
166 		case 0x04: dst = g_strdup_printf("%cE]", '\xc1'); break;
167 		case 0x05: dst = g_strdup_printf("%cF]", '\xc1'); break;
168 		case 0x06: dst = g_strdup_printf("%cG]", '\xc1'); break;
169 		case 0x07: dst = g_strdup_printf("%cH]", '\xc1'); break;
170 		case 0x08: dst = g_strdup_printf("%cI]", '\xc1'); break;
171 		case 0x09: dst = g_strdup_printf("%cJ]", '\xc1'); break;
172 
173 		default:   dst = g_strdup_printf("%c?]", '\xc1'); break;
174 		}
175 		break;
176 
177 	case 0x5D:			/* List: L1 to L6 or L1 to L0 */
178 		if (model == CALC_TI73)
179 		{
180 			// TI73 begins at L0
181 			dst = g_strdup_printf("L%c", src[1] + '\x80');
182 		}
183 		else
184 		{
185 			// TI8x begins at L1
186 			switch(tok2)
187 			{
188 			case 0x00: dst = g_strdup_printf("L%c", '\x81'); break;
189 			case 0x01: dst = g_strdup_printf("L%c", '\x82'); break;
190 			case 0x02: dst = g_strdup_printf("L%c", '\x83'); break;
191 			case 0x03: dst = g_strdup_printf("L%c", '\x84'); break;
192 			case 0x04: dst = g_strdup_printf("L%c", '\x85'); break;
193 			case 0x05: dst = g_strdup_printf("L%c", '\x86'); break;
194 			case 0x06: dst = g_strdup_printf("L%c", '\x87'); break;
195 			case 0x07: dst = g_strdup_printf("L%c", '\x88'); break;
196 			case 0x08: dst = g_strdup_printf("L%c", '\x89'); break;
197 			case 0x09: dst = g_strdup_printf("L%c", '\x80'); break;
198 
199 			case 0x40: dst = g_strdup("IDList"); break;
200 
201 			default: // named list (TI84+/USB)
202 				dst = g_malloc0(9);
203 				for (i = 0; i < 7; i++)
204 				{
205 					dst[i] = src[i + 1];
206 				}
207 				break;
208 			}
209 		}
210 		break;
211 
212 	case 0x5E:			/* Equations: Y1 to Y0, X1t, ... */
213 		switch(tok2)
214 		{
215 		case 0x10: dst = g_strdup_printf("Y%c", '\x81'); break;
216 		case 0x11: dst = g_strdup_printf("Y%c", '\x82'); break;
217 		case 0x12: dst = g_strdup_printf("Y%c", '\x83'); break;
218 		case 0x13: dst = g_strdup_printf("Y%c", '\x84'); break;
219 		case 0x14: dst = g_strdup_printf("Y%c", '\x85'); break;
220 		case 0x15: dst = g_strdup_printf("Y%c", '\x86'); break;
221 		case 0x16: dst = g_strdup_printf("Y%c", '\x87'); break;
222 		case 0x17: dst = g_strdup_printf("Y%c", '\x88'); break;
223 		case 0x18: dst = g_strdup_printf("Y%c", '\x89'); break;
224 		case 0x19: dst = g_strdup_printf("Y%c", '\x80'); break;
225 
226 		case 0x20: dst = g_strdup_printf("X%c%c", '\x81', '\x0d'); break;
227 		case 0x21: dst = g_strdup_printf("Y%c%c", '\x81', '\x0d'); break;
228 		case 0x22: dst = g_strdup_printf("X%c%c", '\x82', '\x0d'); break;
229 		case 0x23: dst = g_strdup_printf("Y%c%c", '\x82', '\x0d'); break;
230 		case 0x24: dst = g_strdup_printf("X%c%c", '\x83', '\x0d'); break;
231 		case 0x25: dst = g_strdup_printf("Y%c%c", '\x83', '\x0d'); break;
232 		case 0x26: dst = g_strdup_printf("X%c%c", '\x84', '\x0d'); break;
233 		case 0x27: dst = g_strdup_printf("Y%c%c", '\x84', '\x0d'); break;
234 		case 0x28: dst = g_strdup_printf("X%c%c", '\x85', '\x0d'); break;
235 		case 0x29: dst = g_strdup_printf("Y%c%c", '\x85', '\x0d'); break;
236 		case 0x2a: dst = g_strdup_printf("X%c%c", '\x86', '\x0d'); break;
237 		case 0x2b: dst = g_strdup_printf("Y%c%c", '\x86', '\x0d'); break;
238 
239 		case 0x40: dst = g_strdup_printf("r%c", '\x81'); break;
240 		case 0x41: dst = g_strdup_printf("r%c", '\x82'); break;
241 		case 0x42: dst = g_strdup_printf("r%c", '\x83'); break;
242 		case 0x43: dst = g_strdup_printf("r%c", '\x84'); break;
243 		case 0x44: dst = g_strdup_printf("r%c", '\x85'); break;
244 		case 0x45: dst = g_strdup_printf("r%c", '\x86'); break;
245 
246 		case 0x80:
247 			if (model == CALC_TI82)
248 			{
249 				dst = g_strdup_printf("U%c", '\xd7');
250 			}
251 			else if (model == CALC_TI73)
252 			{
253 				dst = g_strdup_printf("C\x81");
254 			}
255 			else
256 			{
257 				dst = g_strdup("u");
258 			}
259 			break;
260 
261 		case 0x81:
262 			if (model == CALC_TI82)
263 			{
264 				dst = g_strdup_printf("V%c", '\xd7');
265 			}
266 			else if (model == CALC_TI73)
267 			{
268 				dst = g_strdup_printf("C\x82");
269 			}
270 			else
271 			{
272 				dst = g_strdup("v");
273 			}
274 			break;
275 
276 		case 0x82:
277 			if (model == CALC_TI82)
278 			{
279 				dst = g_strdup_printf("W%c", '\xd7');
280 			}
281 			else if (model == CALC_TI73)
282 			{
283 				dst = g_strdup_printf("C\x83");
284 			}
285 			else
286 			{
287 				dst = g_strdup("w");
288 			}
289 			break;
290 
291 		case 0x83:
292 			if (model == CALC_TI73)
293 			{
294 				dst = g_strdup_printf("C\x84");
295 			}
296 			else
297 			{
298 				dst = g_strdup("?");
299 			}
300 			break;
301 
302 		default: dst = g_strdup("?"); break;
303 		}
304 		break;
305 
306 	case 0x60:			/* Pictures */
307 		if (model == CALC_TI73)
308 		{
309 			dst = g_strdup_printf("Pic%d", tok2);
310 		}
311 		else if (tok2 != 0x09)
312 		{
313 			dst = g_strdup_printf("Pic%d", tok2 + 1);
314 		}
315 		else
316 		{
317 			dst = g_strdup("Pic0");
318 		}
319 		break;
320 
321 	case 0x61:			/* GDB */
322 		if (model == CALC_TI73)
323 		{
324 			dst = g_strdup_printf("GDB%d", tok2);
325 		}
326 		else if (tok2 != 0x09)
327 		{
328 			dst = g_strdup_printf("GDB%d", tok2 + 1);
329 		}
330 		else
331 		{
332 			dst = g_strdup("GDB0");
333 		}
334 		break;
335 
336 	case 0x62:
337 		switch(tok2)
338 		{
339 		case 0x01: dst = g_strdup_printf("ReqEq"); break;
340 		case 0x02: dst = g_strdup_printf("n"); break;
341 		case 0x03: dst = g_strdup_printf("%c", '\xcb'); break;
342 		case 0x04: dst = g_strdup_printf("%c%c", '\xc6', 'x'); break;
343 		case 0x05: dst = g_strdup_printf("%c%c%c", '\xc6', 'x', '\x12'); break;
344 		case 0x06: dst = g_strdup_printf("%c%c", 'S', 'x'); break;
345 		case 0x07: dst = g_strdup_printf("%c%c", '\xc7', 'x'); break;
346 		case 0x08: dst = g_strdup_printf("minX"); break;
347 		case 0x09: dst = g_strdup_printf("maxX"); break;
348 		case 0x0a: dst = g_strdup_printf("minY"); break;
349 		case 0x0b: dst = g_strdup_printf("maxY"); break;
350 		case 0x0c: dst = g_strdup_printf("%c", '\xcc'); break;
351 		case 0x0d: dst = g_strdup_printf("%c%c", '\xc6', 'y'); break;
352 		case 0x0e: dst = g_strdup_printf("%c%c%c", '\xc6', 'y', '\x12'); break;
353 		case 0x0f: dst = g_strdup_printf("%c%c", 'S', 'y'); break;
354 		case 0x10: dst = g_strdup_printf("%c%c", '\xc7', 'y'); break;
355 		case 0x11: dst = g_strdup_printf("%c%c%c", '\xc6', 'x', 'y'); break;
356 		case 0x12: dst = g_strdup_printf("%c", 'r'); break;
357 		case 0x13: dst = g_strdup_printf("Med"); break;
358 		case 0x14: dst = g_strdup_printf("%c%c", 'Q', '\x81'); break;
359 		case 0x15: dst = g_strdup_printf("%c%c", 'Q', '\x83'); break;
360 		case 0x16: dst = g_strdup_printf("a"); break;
361 		case 0x17: dst = g_strdup_printf("b"); break;
362 		case 0x18: dst = g_strdup_printf("c"); break;
363 		case 0x19: dst = g_strdup_printf("d"); break;
364 		case 0x1a: dst = g_strdup_printf("e"); break;
365 		case 0x1b: dst = g_strdup_printf("%c%c", 'x', '\x81'); break;
366 		case 0x1c: dst = g_strdup_printf("%c%c", 'x', '\x82'); break;
367 		case 0x1d: dst = g_strdup_printf("%c%c", 'x', '\x83'); break;
368 		case 0x1e: dst = g_strdup_printf("%c%c", 'y', '\x81'); break;
369 		case 0x1f: dst = g_strdup_printf("%c%c", 'y', '\x82'); break;
370 		case 0x20: dst = g_strdup_printf("%c%c", 'y', '\x83'); break;
371 		case 0x21: dst = g_strdup_printf("%c", '\xd7'); break;
372 		case 0x22: dst = g_strdup_printf("p"); break;
373 		case 0x23: dst = g_strdup_printf("z"); break;
374 		case 0x24: dst = g_strdup_printf("t"); break;
375 		case 0x25: dst = g_strdup_printf("%c%c", '\xd9', '\x12'); break;
376 		case 0x26: dst = g_strdup_printf("%c", '\xda'); break;
377 		case 0x27: dst = g_strdup_printf("df"); break;
378 		case 0x28: dst = g_strdup_printf("%c", '\xd8'); break;
379 		case 0x29: dst = g_strdup_printf("%c%c", '\xd8', '\x81'); break;
380 		case 0x2a: dst = g_strdup_printf("%c%c", '\xd8', '\x82'); break;
381 		case 0x2b: dst = g_strdup_printf("%c%c", '\xd8', '\x81'); break;
382 		case 0x2c: dst = g_strdup_printf("Sx%c", '\x81'); break;
383 		case 0x2d: dst = g_strdup_printf("n%c", '\x81'); break;
384 		case 0x2e: dst = g_strdup_printf("%c%c", '\xcb', '\x82'); break;
385 		case 0x2f: dst = g_strdup_printf("Sx%c", '\x82'); break;
386 		case 0x30: dst = g_strdup_printf("n%c", '\x82'); break;
387 		case 0x31: dst = g_strdup_printf("Sxp"); break;
388 		case 0x32: dst = g_strdup_printf("lower"); break;
389 		case 0x33: dst = g_strdup_printf("upper"); break;
390 		case 0x34: dst = g_strdup_printf("s"); break;
391 		case 0x35: dst = g_strdup_printf("r%c", '\x12'); break;
392 		case 0x36: dst = g_strdup_printf("R%c", '\x12'); break;
393 		case 0x37: dst = g_strdup_printf("df"); break;
394 		case 0x38: dst = g_strdup_printf("SS"); break;
395 		case 0x39: dst = g_strdup_printf("MS"); break;
396 		case 0x3a: dst = g_strdup_printf("df"); break;
397 		case 0x3b: dst = g_strdup_printf("SS"); break;
398 		case 0x3c: dst = g_strdup_printf("MS"); break;
399 		default: dst = g_strdup("_"); break;
400 		}
401 		break;
402 
403 	case 0x63:
404 		switch(tok2)
405 		{
406 		case 0x00: dst = g_strdup_printf("ZXscl"); break;
407 		case 0x01: dst = g_strdup_printf("ZYscl"); break;
408 		case 0x02: dst = g_strdup_printf("Xscl"); break;
409 		case 0x03: dst = g_strdup_printf("Yscl"); break;
410 		case 0x04: dst = g_strdup_printf("U%cStart", '\xd7'); break;
411 		case 0x05: dst = g_strdup_printf("V%cStart", '\xd7'); break;
412 		case 0x06: dst = g_strdup_printf("U%c-%c", '\xd7', '\x81'); break;
413 		case 0x07: dst = g_strdup_printf("V%c-%c", '\xd7', '\x81'); break;
414 		case 0x08: dst = g_strdup_printf("ZU%cStart", '\xd7'); break;
415 		case 0x09: dst = g_strdup_printf("ZV%cStart", '\xd7'); break;
416 		case 0x0a: dst = g_strdup_printf("Xmin"); break;
417 		case 0x0b: dst = g_strdup_printf("Xmax"); break;
418 		case 0x0c: dst = g_strdup_printf("Ymin"); break;
419 		case 0x0d: dst = g_strdup_printf("Ymax"); break;
420 		case 0x0e: dst = g_strdup_printf("Tmin"); break;
421 		case 0x0f: dst = g_strdup_printf("Tmax"); break;
422 		case 0x10: dst = g_strdup_printf("%cmin", '\x5b'); break;
423 		case 0x11: dst = g_strdup_printf("%cmax", '\x5b'); break;
424 		case 0x12: dst = g_strdup_printf("ZXmin"); break;
425 		case 0x13: dst = g_strdup_printf("ZXmax"); break;
426 		case 0x14: dst = g_strdup_printf("ZYmin"); break;
427 		case 0x15: dst = g_strdup_printf("ZYmax"); break;
428 		case 0x16: dst = g_strdup_printf("Z%cmin", '\x5b'); break;
429 		case 0x17: dst = g_strdup_printf("Z%cmax", '\x5b'); break;
430 		case 0x18: dst = g_strdup_printf("ZTmin"); break;
431 		case 0x19: dst = g_strdup_printf("ZTmax"); break;
432 		case 0x1a: dst = g_strdup_printf("TblMin"); break;
433 		case 0x1b: dst = g_strdup_printf("%cMin", '\xd7'); break;
434 		case 0x1c: dst = g_strdup_printf("Z%cMin", '\xd7'); break;
435 		case 0x1d: dst = g_strdup_printf("%cMax", '\xd7'); break;
436 		case 0x1e: dst = g_strdup_printf("Z%cMax", '\xd7'); break;
437 		case 0x1f: dst = g_strdup_printf("%cStart", '\xd7'); break;
438 		case 0x20: dst = g_strdup_printf("Z%cStart", '\xd7'); break;
439 		case 0x21: dst = g_strdup_printf("%cTbl", '\xbe'); break;
440 		case 0x22: dst = g_strdup_printf("Tstep"); break;
441 		case 0x23: dst = g_strdup_printf("%cstep", '\x5b'); break;
442 		case 0x24: dst = g_strdup_printf("ZTstep"); break;
443 		case 0x25: dst = g_strdup_printf("Z%cstep", '\x5b'); break;
444 		case 0x26: dst = g_strdup_printf("%cX", '\xbe'); break;
445 		case 0x27: dst = g_strdup_printf("%cY", '\xbe'); break;
446 		case 0x28: dst = g_strdup_printf("XFact"); break;
447 		case 0x29: dst = g_strdup_printf("YFact"); break;
448 		case 0x2a: dst = g_strdup_printf("TblInput"); break;
449 		case 0x2b: dst = g_strdup_printf("N"); break;
450 		case 0x2c: dst = g_strdup_printf("I%c", '\x25'); break;
451 		case 0x2d: dst = g_strdup_printf("PV"); break;
452 		case 0x2e: dst = g_strdup_printf("PMT"); break;
453 		case 0x2f: dst = g_strdup_printf("FV"); break;
454 		case 0x30: dst = g_strdup_printf("Xres"); break;
455 		case 0x31: dst = g_strdup_printf("ZXres"); break;
456 		default: dst = g_strdup("_"); break;
457 		}
458 		break;
459 
460 	case 0xAA:
461 		if (model == CALC_TI73)
462 		{
463 			dst = g_strdup_printf("Str%d", tok2);
464 		}
465 		else if (tok2 != 0x09)
466 		{
467 			dst = g_strdup_printf("Str%d", tok2 + 1);
468 		}
469 		else
470 		{
471 			dst = g_strdup("Str0");
472 		}
473 		break;
474 
475 	default:
476 		dst = g_strdup("12345678");
477 		strncpy(dst, src, 8);
478 		dst[8] = '\0';
479 		break;
480 	}
481 
482 	return dst;
483 }
484 
485 /**
486  * ticonv_varname_detokenize:
487  * @model: hand-held model
488  * @src: binary string to detokenize
489  *
490  * This function translates a binary variable name (as used on TI8x) into a human readable one.
491  *
492  * Return value: a newly allocated string. Must be freed using ticonv_varname_free() when no longer used.
493  **/
ticonv_varname_detokenize(CalcModel model,const char * src,unsigned char type)494 TIEXPORT4 char* TICALL ticonv_varname_detokenize(CalcModel model, const char *src, unsigned char type)
495 {
496 	char *dst;
497 
498 	if (src == NULL)
499 	{
500 		return g_strdup("________");
501 	}
502 
503 	switch (model)
504 	{
505 	case CALC_TI73:
506 	case CALC_TI82:
507 	case CALC_TI83:
508 	case CALC_TI83P:
509 	case CALC_TI84P:
510 	case CALC_TI84PC:
511 		dst = detokenize_vartype(model, src, type);
512 		if (dst)
513 		{
514 			return dst;
515 		}
516 		return detokenize_varname(model, src, type);
517 	case CALC_TI85:
518 	case CALC_TI86:
519 		dst = detokenize_vartype(model, src, type);
520 		if (dst)
521 		{
522 			return dst;
523 		}
524 	case CALC_TI89:
525 	case CALC_TI89T:
526 	case CALC_TI92:
527 	case CALC_TI92P:
528 	case CALC_V200:
529 		return g_strdup(src);
530 	case CALC_TI84P_USB:
531 	case CALC_TI84PC_USB:
532 	case CALC_TI83PCE_USB:
533 	case CALC_TI84PCE_USB:
534 	case CALC_TI82A_USB:
535 	case CALC_TI84PT_USB:
536 	case CALC_TI89T_USB:
537 		return g_strdup(src);
538 	case CALC_NSPIRE:
539 		return g_strdup(src);
540 	default:
541 		return g_strdup("________");
542 	}
543 }
544 
545 //---
546 
shift(int v)547 static int shift(int v)
548 {
549 	return (v == 0) ? 9 : v-1;
550 }
551 
552 //FIXME: does not work with named list because we should pass the vartype, too
553 /**
554  * ticonv_varname_tokenize:
555  * @model: hand-held model
556  * @src: binary string to tokenize
557  *
558  * This function tries and translates a human-readable variable name into a binary name (as used on TI8x).
559  *
560  * Return value: a newly allocated string. Must be freed using ticonv_varname_free() when no longer used.
561  **/
ticonv_varname_tokenize(CalcModel model,const char * src_,unsigned char type)562 TIEXPORT4 char* TICALL ticonv_varname_tokenize(CalcModel model, const char *src_, unsigned char type)
563 {
564 	const unsigned char *src = (const unsigned char *)src_;
565 
566 	if (src == NULL)
567 	{
568 		return NULL;
569 	}
570 
571 	switch(model)
572 	{
573 		case CALC_TI73:
574 			if (!strcmp("Window", src_) || type == 0x0F)
575 			{
576 				return g_strdup("");
577 			}
578 			if (!strcmp("TblSet", src_) || type == 0x11)
579 			{
580 				return g_strdup("");
581 			}
582 		break;
583 		case CALC_TI82:
584 			if (!strcmp("Window", src_) || type == 0x0B)
585 			{
586 				return g_strdup("");
587 			}
588 			if (!strcmp("RclWin", src_) || type == 0x0C)
589 			{
590 				return g_strdup("");
591 			}
592 			if (!strcmp("TblSet", src_) || type == 0x0D)
593 			{
594 				return g_strdup("");
595 			}
596 		break;
597 		case CALC_TI83:
598 		case CALC_TI83P:
599 		case CALC_TI84P:
600 		case CALC_TI84PC:
601 			if (!strcmp("Window", src_) || type == 0x0F)
602 			{
603 				return g_strdup("");
604 			}
605 			if (!strcmp("RclWin", src_) || type == 0x10)
606 			{
607 				return g_strdup("");
608 			}
609 			if (!strcmp("TblSet", src_) || type == 0x11)
610 			{
611 				return g_strdup("");
612 			}
613 		break;
614 		case CALC_TI85:
615 		case CALC_TI86:
616 			if (!strcmp("Func", src_)  || type == 0x17)
617 			{
618 				return g_strdup("");
619 			}
620 			if (!strcmp("Pol", src_)   || type == 0x18)
621 			{
622 				return g_strdup("");
623 			}
624 			if (!strcmp("Param", src_) || type == 0x19)
625 			{
626 				return g_strdup("");
627 			}
628 			if (!strcmp("DifEq", src_) || type == 0x1A)
629 			{
630 				return g_strdup("");
631 			}
632 			if (!strcmp("ZRCL", src_)  || type == 0x1B)
633 			{
634 				return g_strdup("");
635 			}
636 		break;
637 		default:
638 		break;
639 	}
640 
641 	if (type == 0x01 && (model == CALC_TI83P || model == CALC_TI84P || model == CALC_TI84PC))
642 	{
643 		// Named Lists
644 		gchar *str = g_malloc0(9);
645 
646 		str[0] = 0x5D;
647 		strncpy(str+1, src_, 7);
648 		str[8] = '\0';
649 
650 		return str;
651 	}
652 
653 	if (src[0] == '[' && src[2] == ']' && strlen(src_) == 3)
654 	{
655 		// matrices
656 		return g_strdup_printf("%c%c", 0x5C, src[1] - 'A');
657 	}
658 	else if (src[0] == 'L' && (src[1] >= 128 && src[1] <= 137) && strlen(src_) == 2)
659 	{
660 		// lists
661 		return g_strdup_printf("%c%c", 0x5D, (model == CALC_TI73 ? src[1] - 0x80 : shift(src[1] - 0x80)));
662 	}
663 	else if (src[0] == 'Y' && (src[1] >= 128 && src[1] <= 137) && strlen(src_) == 2)
664 	{
665 		// cartesian equations
666 		return g_strdup_printf("%c%c", 0x5E, 0x10 + shift(src[1] - 0x80));
667 	}
668 	else if (src[0] == 'X' && (src[1] >= 128 && src[1] <= 133) && strlen(src_) == 3)
669 	{
670 		// parametric equations
671 		return g_strdup_printf("%c%c", 0x5E, 0x20 + 2*(src[1] - 0x81)+0);
672 	}
673 	else if (src[0] == 'Y' && (src[1] >= 128 && src[1] <= 133) && strlen(src_) == 3)
674 	{
675 		// parametric equations
676 		return g_strdup_printf("%c%c", 0x5E, 0x20 + 2*(src[1] - 0x81)+1);
677 	}
678 	else if (src[0] == 'r' && (src[1] >= 128 && src[1] <= 133) && strlen(src_) == 2)
679 	{
680 		// polar equations
681 		return g_strdup_printf("%c%c", 0x5E, 0x40 + (src[1] - 0x81));
682 	}
683 	else if (model == CALC_TI73 && src[0] == 'C' && (src[1] >= 128 && src[1] <= 131) && strlen(src_) == 2)
684 	{
685 		// constant equations
686 		return g_strdup_printf("%c%c", 0x5E, 0x80 + shift(src[1] - 0x80));
687 	}
688 	else if (src[0] == 2 && strlen(src_) == 1)
689 	{
690 		return g_strdup_printf("%c%c", 0x5E, 0x80);
691 	}
692 	else if (src[0] == 3 && strlen(src_) == 1)
693 	{
694 		return g_strdup_printf("%c%c", 0x5E, 0x81);
695 	}
696 	else if (src[0] == 4 && strlen(src_) == 1)
697 	{
698 		return g_strdup_printf("%c%c", 0x5E, 0x82);
699 	}
700 	else if (src[0] == 'P' && src[1] == 'i' && src[2] == 'c' && src[3] >= '0' && src[3] <= '9' && strlen(src_) == 4)
701 	{
702 		// pictures
703 		return g_strdup_printf("%c%c", 0x60, (model == CALC_TI73 ? src[3] - '0' : shift(src[3] - '0')));
704 	}
705 	else if (src[0] == 'G' && src[1] == 'D' && src[2] == 'B' && src[3] >= '0' && src[3] <= '9' && strlen(src_) == 4)
706 	{
707 		// gdb
708 		return g_strdup_printf("%c%c", 0x61, (model == CALC_TI73 ? src[3] - '0' : shift(src[3] - '0')));
709 	}
710 	else if (src[0] == 'S' && src[1] == 't' && src[2] == 'r' && src[3] >= '0' && src[3] <= '9' && strlen(src_) == 4)
711 	{
712 		// strings
713 		return g_strdup_printf("%c%c", 0xAA, (model == CALC_TI73 ? src[3] - '0' : shift(src[3] - '0')));
714 	}
715 	else if (type == 0x1A && !strncmp((const char*) src, "Image", 5) && src[5] >= '0' && src[5] <= '9')
716 	{
717 		// images
718 		return g_strdup_printf("%c%c", 0x3C, shift(src[5] - '0'));
719 	}
720 
721 	return g_strdup(src_);
722 }
723 
724 /**
725  * ticonv_varname_free:
726  * @varname: previously allocated varname string to be freed.
727  *
728  * This function frees a varname previously allocated by ticonv_varname_detokenize() or ticonv_varname_tokenize().
729  **/
ticonv_varname_free(char * varname)730 TIEXPORT4 void TICALL ticonv_varname_free(char * varname)
731 {
732 	g_free(varname);
733 }
734