This source file includes following definitions.
- FUN1
- FUN2
- FUN0
- FUN2
- FUN1
1 %{
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 %}
21
22
23 %right '?' ':'
24
25 %left '&'
26 %nonassoc '=' NE
27 %nonassoc '<' LE '>' GE
28 %left '+' '-'
29 %left '*' '/' '%'
30 %right '^'
31 %left NEG '!'
32
33 %token L_CELL L_RANGE
34 %token L_VAR
35
36 %token L_CONST
37 %token L_FN0 L_FN1 L_FN2 L_FN3 L_FN4 L_FNN
38 %token L_FN1R L_FN2R L_FN3R L_FN4R L_FNNR
39
40 %token L_LE L_NE L_GE
41
42 %{
43 #include "funcdef.h"
44
45 #include <ctype.h>
46
47 #define obstack_chunk_alloc ck_malloc
48 #define obstack_chunk_free free
49 #include "obstack.h"
50 #include "sysdef.h"
51
52 #include "global.h"
53 #include "errors.h"
54 #include "node.h"
55 #include "eval.h"
56 #include "ref.h"
57
58 int yylex ();
59 #ifdef __STDC__
60 void yyerror (char *);
61 #else
62 void yyerror ();
63 #endif
64 VOIDSTAR parse_hash;
65 extern VOIDSTAR hash_find();
66
67
68 unsigned char fnin[] = {
69 SUM, DIFF, DIV, PROD, MOD, POW, EQUAL, IF, CONCAT, 0
70 };
71
72 #define YYSTYPE _y_y_s_t_y_p_e
73 typedef struct node *YYSTYPE;
74 YYSTYPE parse_return;
75 #ifdef __STDC__
76 YYSTYPE make_list (YYSTYPE, YYSTYPE);
77 #else
78 YYSTYPE make_list ();
79 #endif
80
81 char *instr;
82 int parse_error = 0;
83 extern struct obstack tmp_mem;
84
85 %}
86 %%
87 line: exp
88 { parse_return=$1; }
89 | error {
90 if(!parse_error)
91 parse_error=PARSE_ERR;
92 parse_return=0; }
93 ;
94
95 exp: L_CONST
96 | cell
97 | L_FN0 '(' ')' {
98 $$=$1; }
99 | L_FN1 '(' exp ')' {
100 ($1)->n_x.v_subs[0]=$3;
101 ($1)->n_x.v_subs[1]=(struct node *)0;
102 $$=$1; }
103 | L_FN2 '(' exp ',' exp ')' {
104 ($1)->n_x.v_subs[0]=$3;
105 ($1)->n_x.v_subs[1]=$5;
106 $$=$1; }
107 | L_FN3 '(' exp ',' exp ',' exp ')' {
108 ($1)->n_x.v_subs[0]=make_list($3,$5);
109 ($1)->n_x.v_subs[1]=$7;
110 $$=$1;}
111 | L_FN4 '(' exp ',' exp ',' exp ',' exp ')' {
112 ($1)->n_x.v_subs[0]=make_list($3,$5);
113 ($1)->n_x.v_subs[1]=make_list($7,$9);
114 $$=$1;}
115 | L_FNN '(' exp_list ')' {
116 ($1)->n_x.v_subs[0]=(struct node *)0;
117 ($1)->n_x.v_subs[1]=$3;
118 $$=$1; }
119 | L_FN1R '(' L_RANGE ')' {
120 $1->n_x.v_subs[0]=$3;
121 $$=$1; }
122 | L_FN1R '(' L_VAR ')' {
123 $1->n_x.v_subs[0]=$3;
124 $$=$1; }
125
126 | L_FN2R '(' L_RANGE ',' exp ')' {
127 $1->n_x.v_subs[0]=$3;
128 $1->n_x.v_subs[1]=$5;
129 $$=$1; }
130 | L_FN2R '(' L_VAR ',' exp ')' {
131 $1->n_x.v_subs[0]=$3;
132 $1->n_x.v_subs[1]=$5;
133 $$=$1; }
134
135
136 | L_FN2R '(' L_RANGE ',' exp ',' exp ')' {
137 if($1->comp_value!=F_INDEX)
138 parse_error=PARSE_ERR;
139 $1->comp_value=F_INDEX2;
140 $1->n_x.v_subs[0]=make_list($3,$5);
141 $1->n_x.v_subs[1]=$7;
142 $$=$1; }
143 | L_FN2R '(' L_VAR ',' exp ',' exp ')' {
144 if($1->comp_value!=F_INDEX)
145 parse_error=PARSE_ERR;
146 $1->comp_value=F_INDEX2;
147 $1->n_x.v_subs[0]=make_list($3,$5);
148 $1->n_x.v_subs[1]=$7;
149 $$=$1; }
150
151 | L_FN3R '(' L_RANGE ',' exp ',' exp ')' {
152 ($1)->n_x.v_subs[0]=make_list($3,$5);
153 ($1)->n_x.v_subs[1]=$7;
154 $$=$1;}
155 | L_FN3R '(' L_VAR ',' exp ',' exp ')' {
156 ($1)->n_x.v_subs[0]=make_list($3,$5);
157 ($1)->n_x.v_subs[1]=$7;
158 $$=$1;}
159
160 | L_FNNR '(' range_exp_list ')' {
161 ($1)->n_x.v_subs[0]=(struct node *)0;
162 ($1)->n_x.v_subs[1]=$3;
163 $$=$1; }
164 | exp '?' exp ':' exp {
165 $2->comp_value=IF;
166 $2->n_x.v_subs[0]=$4;
167 $2->n_x.v_subs[1]=$5;
168 $4->n_x.v_subs[0]=$1;
169 $4->n_x.v_subs[1]=$3;
170 $$=$2; }
171
172
173
174
175 | exp '&' exp {
176 $2->n_x.v_subs[0]=$1;
177 $2->n_x.v_subs[1]=$3;
178 $$ = $2; }
179 | exp '<' exp {
180 $2->n_x.v_subs[0]=$1;
181 $2->n_x.v_subs[1]=$3;
182 $$ = $2; }
183 | exp LE exp {
184 $2->n_x.v_subs[0]=$1;
185 $2->n_x.v_subs[1]=$3;
186 $$ = $2; }
187 | exp '=' exp {
188 $2->n_x.v_subs[0]=$1;
189 $2->n_x.v_subs[1]=$3;
190 $$ = $2; }
191 | exp NE exp {
192 $2->n_x.v_subs[0]=$1;
193 $2->n_x.v_subs[1]=$3;
194 $$ = $2; }
195 | exp '>' exp {
196 $2->n_x.v_subs[0]=$1;
197 $2->n_x.v_subs[1]=$3;
198 $$ = $2; }
199 | exp GE exp {
200 $2->n_x.v_subs[0]=$1;
201 $2->n_x.v_subs[1]=$3;
202 $$ = $2; }
203 | exp '+' exp {
204 $2->n_x.v_subs[0]=$1;
205 $2->n_x.v_subs[1]=$3;
206 $$ = $2; }
207 | exp '-' exp {
208 $2->n_x.v_subs[0]=$1;
209 $2->n_x.v_subs[1]=$3;
210 $$ = $2; }
211 | exp '*' exp {
212 $2->n_x.v_subs[0]=$1;
213 $2->n_x.v_subs[1]=$3;
214 $$ = $2; }
215 | exp '/' exp {
216 $2->n_x.v_subs[0]=$1;
217 $2->n_x.v_subs[1]=$3;
218 $$ = $2; }
219 | exp '%' exp {
220 $2->n_x.v_subs[0]=$1;
221 $2->n_x.v_subs[1]=$3;
222 $$ = $2; }
223 | exp '^' exp {
224 $2->n_x.v_subs[0]=$1;
225 $2->n_x.v_subs[1]=$3;
226 $$ = $2; }
227 | '-' exp %prec NEG {
228 if($2->comp_value==CONST_FLT) {
229 $2->n_x.v_float= -($2->n_x.v_float);
230
231 $$=$2;
232 } else if($2->comp_value==CONST_INT) {
233 $2->n_x.v_int= -($2->n_x.v_int);
234
235 $$=$2;
236 } else {
237 $1->comp_value = NEGATE;
238 $1->n_x.v_subs[0]=$2;
239 $1->n_x.v_subs[1]=(struct node *)0;
240 $$ = $1;
241 } }
242 | '!' exp {
243 $1->n_x.v_subs[0]=$2;
244 $1->n_x.v_subs[1]=(struct node *)0;
245 $$ = $1; }
246 | '(' exp ')'
247 { $$ = $2; }
248 | '(' exp error {
249 if(!parse_error)
250 parse_error=NO_CLOSE;
251 }
252
253
254
255
256 | '(' error {
257 if(!parse_error)
258 parse_error=NO_CLOSE;
259 }
260 ;
261
262
263 exp_list: exp
264 { $$ = make_list($1, 0); }
265 | exp_list ',' exp
266 { $$ = make_list($3, $1); }
267 ;
268
269 range_exp: L_RANGE
270 | exp
271 ;
272
273 range_exp_list: range_exp
274 { $$=make_list($1, 0); }
275 | range_exp_list ',' range_exp
276 { $$=make_list($3,$1); }
277 ;
278
279 cell: L_CELL
280 { $$=$1; }
281 | L_VAR
282 ;
283 %%
284
285 void
286 yyerror FUN1(char *, s)
287 {
288 if(!parse_error)
289 parse_error=PARSE_ERR;
290 }
291
292 YYSTYPE
293 make_list FUN2(YYSTYPE, car, YYSTYPE, cdr)
294 {
295 YYSTYPE ret;
296
297 ret=(YYSTYPE)obstack_alloc(&tmp_mem,sizeof(*ret));
298 ret->comp_value = 0;
299 ret->n_x.v_subs[0]=car;
300 ret->n_x.v_subs[1]=cdr;
301 return ret;
302 }
303
304 #define ERROR -1
305
306 extern struct node *yylval;
307
308 #ifdef __STDC__
309 unsigned char parse_cell_or_range (char **,struct rng *);
310 #else
311 unsigned char parse_cell_or_range ();
312 #endif
313
314 int
315 yylex FUN0()
316 {
317 int ch;
318 struct node *new;
319 int isflt;
320 char *begin;
321 char *tmp_str;
322 unsigned char byte_value;
323 int n;
324
325
326 int nn;
327 struct function *fp;
328 int tmp_ch;
329
330 #ifdef TEST
331 if(!instr)
332 return ERROR;
333 #endif
334 while(isspace(*instr))
335 instr++;
336 ch = *instr++;
337 if(ch=='(' || ch==',' || ch==')')
338 return ch;
339
340 new=(struct node *)obstack_alloc(&tmp_mem,sizeof(struct node));
341 new->add_byte=0;
342 new->sub_value=0;
343 switch(ch) {
344 case 0:
345 return 0;
346
347 case '0': case '1': case '2': case '3': case '4': case '5': case '6':
348 case '7': case '8': case '9': case '.':
349 isflt = (ch=='.');
350
351 begin=instr-1;
352 tmp_str=instr;
353
354 while(isdigit(*tmp_str) || (!isflt && *tmp_str=='.' && ++isflt))
355 tmp_str++;
356 if(*tmp_str=='e' || *tmp_str=='E') {
357 isflt=1;
358 tmp_str++;
359 if(*tmp_str=='-' || *tmp_str=='+')
360 tmp_str++;
361 while(isdigit(*tmp_str))
362 tmp_str++;
363 }
364 if(isflt) {
365 new->n_x.v_float=astof((char **)(&begin));
366 byte_value=CONST_FLT;
367 } else {
368 new->n_x.v_int=astol((char **)(&begin));
369 if(begin!=tmp_str) {
370 begin=instr-1;
371 new->n_x.v_float=astof((char **)(&begin));
372 byte_value=CONST_FLT;
373 } else
374 byte_value=CONST_INT;
375 }
376 ch=L_CONST;
377 instr=begin;
378 break;
379
380 case '"':
381 begin=instr;
382 while(*instr && *instr!='"') {
383 if(*instr=='\\' && instr[1])
384 instr++;
385 instr++;
386 }
387 if(!*instr) {
388 parse_error=NO_QUOTE;
389 return ERROR;
390 }
391 tmp_str=new->n_x.v_string=(char *)ck_malloc(1+instr-begin);
392 while(begin!=instr) {
393 unsigned char n;
394
395 if(*begin=='\\') {
396 begin++;
397 if(begin[0]>='0' && begin[0]<='7') {
398 if(begin[1]>='0' && begin[1]<='7') {
399 if(begin[2]>='0' && begin[2]<='7') {
400 n=(begin[2]-'0') + (010 * (begin[1]-'0')) + ( 0100 * (begin[0]-'0'));
401 begin+=3;
402 } else {
403 n=(begin[1]-'0') + (010 * (begin[0]-'0'));
404 begin+=2;
405 }
406 } else {
407 n=begin[0]-'0';
408 begin++;
409 }
410 } else
411 n= *begin++;
412 *tmp_str++= n;
413 } else
414 *tmp_str++= *begin++;
415 }
416 *tmp_str='\0';
417 instr++;
418 byte_value=CONST_STR;
419 ch=L_CONST;
420 break;
421
422 case '+': case '-':
423
424 case '*': case '/': case '%': case '&':
425 case '^': case '=':
426
427 case '?':
428 {
429 unsigned char *ptr;
430
431 for(ptr= fnin;*ptr;ptr++)
432 if(the_funs[*ptr].fn_str[0]==ch)
433 break;
434 #ifdef TEST
435 if(!*ptr)
436 panic("Can't find fnin[] entry for '%c'",ch);
437 #endif
438 byte_value= *ptr;
439 }
440 break;
441
442 case ':':
443 byte_value=IF;
444 break;
445
446 case '!':
447 case '<':
448 case '>':
449 if(*instr!='=') {
450 byte_value = (ch=='<') ? LESS : (ch=='>') ? GREATER : NOT;
451 break;
452 }
453 instr++;
454 byte_value = (ch=='<') ? LESSEQ : (ch=='>') ? GREATEQ : NOTEQUAL;
455 ch = (ch=='<') ? LE : (ch=='>') ? GE : NE;
456 break;
457
458 case '\'':
459 case ';':
460 case '[':
461 case '\\':
462 case ']':
463 case '`':
464 case '{':
465 case '}':
466 case '~':
467 bad_chr:
468 parse_error=BAD_CHAR;
469 return ERROR;
470
471 case '#':
472 begin=instr-1;
473 while(*instr && (isalnum(*instr) || *instr=='_'))
474 instr++;
475 ch= *instr;
476 *instr=0;
477 if(!stricmp(begin,tname))
478 byte_value=F_TRUE;
479 else if(!stricmp(begin,fname))
480 byte_value=F_FALSE;
481 else if(!stricmp(begin,iname) && (begin[4]==0 || !stricmp(begin+4,"inity")))
482 byte_value=CONST_INF;
483 else if(!stricmp(begin,mname) ||
484 !stricmp(begin,"#ninf"))
485 byte_value=CONST_NINF;
486 else if(!stricmp(begin,nname) ||
487 !stricmp(begin,"#nan"))
488 byte_value=CONST_NAN;
489 else {
490 for(n=1;n<=ERR_MAX;n++)
491 if(!stricmp(begin,ename[n]))
492 break;
493 if(n>ERR_MAX)
494 n=BAD_CHAR;
495 new->n_x.v_int=n;
496 byte_value=CONST_ERR;
497 }
498 *instr=ch;
499 ch=L_CONST;
500 break;
501
502 default:
503 if(!a0 && (ch=='@' || ch=='$'))
504 goto bad_chr;
505
506 if(a0 && ch=='@') {
507 begin=instr;
508 while(*instr && (isalpha(*instr) || isdigit(*instr) || *instr=='_'))
509 instr++;
510 n=instr-begin;
511 } else {
512 begin=instr-1;
513 byte_value=parse_cell_or_range(&begin,&(new->n_x.v_rng));
514 if(byte_value) {
515 if((byte_value& ~0x3)==R_CELL)
516 ch=L_CELL;
517 else
518 ch=L_RANGE;
519 instr=begin;
520 break;
521 }
522
523 while(*instr && (isalpha(*instr) || isdigit(*instr) || *instr=='_'))
524 instr++;
525
526 n=instr-begin;
527 while(isspace(*instr))
528 instr++;
529
530 if(*instr!='(') {
531 ch=L_VAR;
532 byte_value=VAR;
533 new->n_x.v_var=find_or_make_var(begin,n);
534 break;
535 }
536 }
537 tmp_ch=begin[n];
538 begin[n]='\0';
539 fp=hash_find(parse_hash,begin);
540 begin[n]=tmp_ch;
541 byte_value= ERROR;
542 if(!fp) {
543 parse_error=BAD_FUNC;
544 return ERROR;
545 }
546
547 if(fp>=the_funs && fp<=&the_funs[USR1])
548 byte_value=fp-the_funs;
549 else {
550 for(nn=0;nn<n_usr_funs;nn++) {
551 if(fp>=&usr_funs[nn][0] && fp<=&usr_funs[nn][usr_n_funs[nn]]) {
552 byte_value=USR1+nn;
553 new->sub_value=fp-&usr_funs[nn][0];
554 break;
555 }
556 }
557 #ifdef TEST
558 if(nn==n_usr_funs) {
559 io_error_msg("Couldn't turn fp into a ##");
560 parse_error=BAD_FUNC;
561 return ERROR;
562 }
563 #endif
564 }
565
566 if(fp->fn_argn&X_J)
567 ch= byte_value==F_IF ? L_FN3 : L_FN2;
568 else if(fp->fn_argt[0]=='R' || fp->fn_argt[0]=='E')
569 ch=L_FN1R-1+fp->fn_argn-X_A0;
570 else
571 ch=L_FN0 + fp->fn_argn-X_A0;
572
573 break;
574 }
575
576 new->comp_value=byte_value;
577 yylval=new;
578 return ch;
579 }
580
581
582
583
584
585
586 unsigned char
587 parse_cell_or_range FUN2(char **,ptr, struct rng *,retp)
588 {
589 if(a0) {
590 unsigned tmpc,tmpr;
591 char *p;
592 int abz = ROWREL|COLREL;
593
594 p= *ptr;
595 tmpc=0;
596 if(*p=='$') {
597 abz-=COLREL;
598 p++;
599 }
600 if(!isalpha(*p))
601 return 0;
602 tmpc=str_to_col(&p);
603 if(tmpc<MIN_COL || tmpc>MAX_COL)
604 return 0;
605 if(*p=='$') {
606 abz-=ROWREL;
607 p++;
608 }
609 if(!isdigit(*p))
610 return 0;
611 for(tmpr=0;isdigit(*p);p++)
612 tmpr=tmpr*10 + *p - '0';
613
614 if(tmpr<MIN_ROW || tmpr>MAX_ROW)
615 return 0;
616
617 if(*p==':' || *p=='.') {
618 unsigned tmpc1,tmpr1;
619
620 abz = ((abz&COLREL) ? LCREL : 0)|((abz&ROWREL) ? LRREL : 0)|HRREL|HCREL;
621 p++;
622 if(*p=='$') {
623 abz-=HCREL;
624 p++;
625 }
626 if(!isalpha(*p))
627 return 0;
628 tmpc1=str_to_col(&p);
629 if(tmpc1<MIN_COL || tmpc1>MAX_COL)
630 return 0;
631 if(*p=='$') {
632 abz-=HRREL;
633 p++;
634 }
635 if(!isdigit(*p))
636 return 0;
637 for(tmpr1=0;isdigit(*p);p++)
638 tmpr1=tmpr1*10 + *p - '0';
639 if(tmpr1<MIN_ROW || tmpr1>MAX_ROW)
640 return 0;
641
642 if(tmpr<tmpr1) {
643 retp->lr=tmpr;
644 retp->hr=tmpr1;
645 } else {
646 retp->lr=tmpr1;
647 retp->hr=tmpr;
648 }
649 if(tmpc<tmpc1) {
650 retp->lc=tmpc;
651 retp->hc=tmpc1;
652 } else {
653 retp->lc=tmpc1;
654 retp->hc=tmpc;
655 }
656 *ptr= p;
657 return RANGE | abz;
658 }
659 retp->lr = retp->hr = tmpr;
660 retp->lc = retp->hc = tmpc;
661 *ptr=p;
662 return R_CELL | abz;
663 } else {
664 char *p;
665 unsigned char retr;
666 unsigned char retc;
667 int ended;
668 long num;
669 CELLREF tmp;
670
671 #define CK_ABS_R(x) if((x)<MIN_ROW || (x)>MAX_ROW) \
672 return 0; \
673 else
674
675 #define CK_REL_R(x) if( ((x)>0 && MAX_ROW-(x)<cur_row) \
676 || ((x)<0 && MIN_ROW-(x)>cur_row)) \
677 return 0; \
678 else
679
680 #define CK_ABS_C(x) if((x)<MIN_COL || (x)>MAX_COL) \
681 return 0; \
682 else
683
684 #define CK_REL_C(x) if( ((x)>0 && MAX_COL-(x)<cur_col) \
685 || ((x)<0 && MIN_COL-(x)>cur_col)) \
686 return 0; \
687 else
688
689 #define MAYBEREL(p) (*(p)=='[' && (isdigit((p)[1]) || (((p)[1]=='+' || (p)[1]=='-') && isdigit((p)[2]))))
690
691 p= *ptr;
692 retr=0;
693 retc=0;
694 ended=0;
695 while(ended==0) {
696 switch(*p) {
697 case 'r':
698 case 'R':
699 if(retr) {
700 ended++;
701 break;
702 }
703 p++;
704 retr=R_CELL;
705 if(isdigit(*p)) {
706 num=astol(&p);
707 CK_ABS_R(num);
708 retp->lr= retp->hr=num;
709 } else if(MAYBEREL(p)) {
710 p++;
711 num=astol(&p);
712 CK_REL_R(num);
713 retp->lr= retp->hr=num+cur_row;
714 retr|=ROWREL;
715 if(*p==':') {
716 retr=RANGE|LRREL|HRREL;
717 p++;
718 num=astol(&p);
719 CK_REL_R(num);
720 retp->hr=num+cur_row;
721 }
722 if(*p++!=']')
723 return 0;
724 } else if(retc || *p=='c' || *p=='C') {
725 retr|=ROWREL;
726 retp->lr= retp->hr=cur_row;
727 } else
728 return 0;
729 if(*p==':' && retr!=(RANGE|LRREL|HRREL)) {
730 retr= (retr&ROWREL) ? RANGE|LRREL : RANGE;
731 p++;
732 if(isdigit(*p)) {
733 num=astol(&p);
734 CK_ABS_R(num);
735 retp->hr=num;
736 } else if(MAYBEREL(p)) {
737 p++;
738 num=astol(&p);
739 CK_REL_R(num);
740 retp->hr=num+cur_row;
741 retr|=HRREL;
742 if(*p++!=']')
743 return 0;
744 } else
745 return 0;
746 }
747
748 if(retc)
749 ended++;
750 break;
751
752 case 'c':
753 case 'C':
754 if(retc) {
755 ended++;
756 break;
757 }
758 p++;
759 retc=R_CELL;
760 if(isdigit(*p)) {
761 num=astol(&p);
762 CK_ABS_C(num);
763 retp->lc= retp->hc=num;
764 } else if(MAYBEREL(p)) {
765 p++;
766 num=astol(&p);
767 CK_REL_C(num);
768 retp->lc= retp->hc=num+cur_col;
769 retc|=COLREL;
770 if(*p==':') {
771 retc=RANGE|LCREL|HCREL;
772 p++;
773 num=astol(&p);
774 CK_REL_C(num);
775 retp->hc=num+cur_col;
776 }
777 if(*p++!=']')
778 return 0;
779 } else if(retr || *p=='r' || *p=='R') {
780 retc|=COLREL;
781 retp->lc= retp->hc=cur_col;
782 } else
783 return 0;
784 if(*p==':' && retc!=(RANGE|LCREL|HCREL)) {
785 retc= (retc&COLREL) ? RANGE|LCREL : RANGE;
786 p++;
787 if(isdigit(*p)) {
788 num=astol(&p);
789 CK_ABS_C(num);
790 retp->hc=num;
791 } else if(MAYBEREL(p)) {
792 p++;
793 num=astol(&p);
794 CK_REL_C(num);
795 retp->hc=num+cur_col;
796 retc|=HCREL;
797 if(*p++!=']')
798 return 0;
799 } else
800 return 0;
801 }
802
803 if(retr)
804 ended++;
805 break;
806 default:
807 if(retr) {
808 *ptr=p;
809 retp->lc=MIN_COL;
810 retp->hc=MAX_COL;
811 if((retr|ROWREL)==(R_CELL|ROWREL))
812 return (retr&ROWREL) ? (RANGE|LRREL|HRREL) : RANGE;
813 else
814 return retr;
815 } else if(retc) {
816 *ptr=p;
817 retp->lr=MIN_ROW;
818 retp->hr=MAX_COL;
819 if((retc|COLREL)==(R_CELL|COLREL))
820 return (retc&COLREL) ? (RANGE|LCREL|HCREL) : RANGE;
821 else
822 return retc;
823 }
824 return 0;
825 }
826 }
827 if(!retr || !retc)
828 return 0;
829 *ptr=p;
830 if(retp->lr>retp->hr)
831 tmp=retp->lr,retp->lr=retp->hr,retp->hr=tmp;
832 if(retp->lc>retp->hc)
833 tmp=retp->lc,retp->lc=retp->hc,retp->hc=tmp;
834
835 if((retr|ROWREL)==(R_CELL|ROWREL)) {
836 if((retc|COLREL)==(R_CELL|COLREL))
837 return retr|retc;
838 return (retr&ROWREL) ? (retc|LRREL|HRREL) : retc;
839 }
840 if((retc|COLREL)==(R_CELL|COLREL))
841 return (retc&COLREL) ? (retr|LCREL|HCREL) : retr;
842 return retr|retc;
843 }
844 }
845
846 int
847 str_to_col FUN1(char **,str)
848 {
849 int ret;
850 char c,cc,ccc;
851 #if MAX_COL>702
852 char cccc;
853 #endif
854
855 ret=0;
856 c=str[0][0];
857 if(!isalpha((cc=str[0][1]))) {
858 (*str)++;
859 return MIN_COL + (isupper(c) ? c-'A' : c-'a');
860 }
861 if(!isalpha((ccc=str[0][2]))) {
862 (*str)+=2;
863 return MIN_COL+26 + (isupper(c) ? c-'A' : c-'a')*26 + (isupper(cc) ? cc-'A' : cc-'a');
864 }
865 #if MAX_COL>702
866 if(!isalpha((cccc=str[0][3]))) {
867 (*str)+=3;
868 return MIN_COL+702 + (isupper(c) ? c-'A' : c-'a')*26*26 + (isupper(cc) ? cc-'A' : cc-'a')*26 + (isupper(ccc) ? ccc-'A' : ccc-'a');
869 }
870 if(!isalpha(str[0][4])) {
871 (*str)+=4;
872 return MIN_COL+18278 + (isupper(c) ? c-'A' : c-'a')*26*26*26 + (isupper(cc) ? cc-'A' : cc-'a')*26*26 + (isupper(ccc) ? ccc-'A' : ccc-'a')*26 + (isupper(cccc) ? cccc-'A' : cccc-'a');
873 }
874 #endif
875 return 0;
876 }