source: trunk/tools/vslick/odin32.e@ 7172

Last change on this file since 7172 was 7161, checked in by bird, 24 years ago

Fixed enumeration of '...' parameter. odin32_funcbox now insert parameters with defaults.

File size: 32.7 KB
Line 
1/* $Id: odin32.e,v 1.10 2001-10-23 02:30:54 bird Exp $
2 *
3 * Visual SlickEdit Documentation Macros.
4 *
5 * Copyright (c) 1999-2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 ****
10 *
11 * This define the following keys:
12 *---------------------------------
13 * Ctrl+Shift+C: Class description box.
14 * Ctrl+Shift+F: Function/method description box.
15 * Ctrl+Shift+M: Module(file) description box
16 * Ctrl+Shift+O: One-liner (comment)
17 *
18 * Ctrl+Shift+G: Global box
19 * Ctrl+Shift+H: Header box
20 * Ctrl+Shift+I: Internal function box
21 * Ctrl+Shift+K: Const/macro box
22 * Ctrl+Shift+S: Struct/Typedef box
23 *
24 * Ctrl+Shift+T:
25 *
26 * Ctrl+Shift+B: KLOGENTRYX(..)
27 * Ctrl+Shift+E: KLOGEXIT(..)
28 * Ctrl+Shift+N: Do kLog stuff for the current file. No questions.
29 * Ctrl+Shift+Q: Do kLog stuff for the current file. Ask a lot of questions.
30 *
31 * Remember to set the correct sOdin32UserName, sOdin32UserEmail and sOdin32UserInitials
32 * before compiling and loading the macros into Visual SlickEdit.
33 *
34 * These macros are compatible with both 3.0(c) and 4.0(b).
35 *
36 */
37defeventtab default_keys
38def 'C-S-A' = odin32_signature
39def 'C-S-B' = odin32_klogentry
40def 'C-S-C' = odin32_classbox
41def 'C-S-E' = odin32_klogexit
42def 'C-S-F' = odin32_funcbox
43def 'C-S-G' = odin32_globalbox
44def 'C-S-H' = odin32_headerbox
45def 'C-S-I' = odin32_intfuncbox
46def 'C-S-K' = odin32_constbox
47def 'C-S-M' = odin32_modulebox
48def 'C-S-N' = odin32_klog_file_no_ask
49def 'C-S-O' = odin32_oneliner
50def 'C-S-Q' = odin32_klog_file_ask
51def 'C-S-S' = odin32_structbox
52def 'C-S-T' = odin32_maketagfile
53
54
55//MARKER. Editor searches for this line!
56#pragma option(redeclvars, on)
57#include 'slick.sh'
58
59/* Remeber to change these! */
60static _str sOdin32UserInitials = "kso";
61static _str sOdin32UserName = "knut st. osmundsen";
62static _str sOdin32UserEmail = "knut.stange.osmundsen@mynd.no";
63
64
65
66/**
67 * Insers a date string. The date is in ISO format.
68 */
69void odin32_date()
70{
71 int i,j;
72 _str date;
73
74 date = _date('U');
75 i = pos("/", date);
76 j = pos("/", date, i+1);
77 month = substr(date, 1, i-1);
78 if (length(month) == 1) month = '0'month;
79 day = substr(date, i+1, j-i-1);
80 if (length(day) == 1) day = '0'day;
81 year = substr(date, j+1);
82 _insert_text(nls("%s-%s-%s", year, month, day));
83}
84
85
86/**
87 * Get the current year.
88 * @returns Current year string.
89 */
90_str odin32_year()
91{
92 date = _date('U');
93 return substr(date, pos("/",date, pos("/",date)+1)+1, 4);
94}
95
96
97/**
98 * Inserts the first line in a box.
99 * @param sTag Not used - box tag.
100 */
101static void odin32_firstline(sTag)
102{
103 begin_line();
104 if (file_eq(p_extension, 'asm'))
105 _insert_text(";\n");
106 else
107 {
108 _insert_text("/");
109 for (i = 0; i < 80-1; i++)
110 _insert_text("*");
111 _insert_text("\n");
112 }
113}
114
115/**
116 * Inserts a line with a '*' in both ends and some text (a) inside.
117 * @param a text.
118 */
119void odin32_starlinestr(a)
120{
121 if (file_eq(p_extension, 'asm'))
122 {
123 _insert_text("; ");
124 _insert_text(a);
125 _insert_text("\n");
126 }
127 else
128 {
129 _insert_text("* ");
130 _insert_text(a);
131 for (i = 0; i < 80-3-length(a); i++)
132 _insert_text(" ");
133 _insert_text("*\n");
134 }
135}
136
137
138/**
139 * Empty line with a '*' in both ends.
140 */
141void odin32_starline()
142{
143 odin32_starlinestr("");
144}
145
146
147/**
148 * Inserts the last line in a box.
149 */
150void odin32_lastline()
151{
152 if (file_eq(p_extension, 'asm'))
153 _insert_text(";\n");
154 else
155 {
156 for (i = 0; i < 80-1; i++)
157 _insert_text("*");
158 _insert_text("/\n");
159 }
160}
161
162
163
164/**
165 * Inserts a signature. Form: "//Initials ISO-date:"
166 * @remark defeventtab
167 */
168void odin32_signature()
169{
170 if (file_eq(p_extension, 'asm'))
171 _insert_text(";"sOdin32UserInitials" ");
172 else
173 _insert_text("//"sOdin32UserInitials" ");
174
175 odin32_date()
176 _insert_text(":");
177}
178
179
180/**
181 * SDS - Classbox(/header).
182 * @remark defeventtab
183 */
184void odin32_classbox()
185{
186 _begin_line();
187 _insert_text("/**\n");
188 _insert_text(" * \n");
189 _insert_text(" * @shortdesc \n");
190 _insert_text(" * @dstruct \n");
191 _insert_text(" * @version \n");
192 _insert_text(" * @verdesc \n");
193 _insert_text(" * @author " sOdin32UserName " (" sOdin32UserEmail ")\n");
194 _insert_text(" * @approval \n");
195 _insert_text(" */\n");
196
197 up(8);
198 p_col += 3;
199}
200
201
202/**
203 * SDS - functionbox(/header).
204 * @remark defeventtab
205 */
206void odin32_funcbox()
207{
208 _begin_line();
209 if (file_eq(p_extension, 'asm'))
210 {
211 _insert_text(";;\n");
212 _insert_text("; \n");
213 _insert_text("; @cproto \n");
214 _insert_text("; @returns \n");
215 _insert_text("; @param \n");
216 _insert_text("; @uses \n");
217 _insert_text("; @equiv \n");
218 _insert_text("; @time \n");
219 _insert_text("; @sketch \n");
220 _insert_text("; @status \n");
221 _insert_text("; @author "sOdin32UserName" (" sOdin32UserEmail ")\n");
222 _insert_text("; @remark \n");
223 up(11);
224 p_col = 3;
225 }
226 else
227 {
228 int cArgs = 1;
229 _str sArgs = "";
230 boolean fFoundFn = !odin32_func_goto_nearest();
231 if (fFoundFn)
232 {
233 sArgs = odin32_getparams();
234 cArgs = odin32_countparams(sArgs);
235 }
236
237 _insert_text("/**\n");
238 _insert_text(" * \n");
239 _insert_text(" * @returns \n");
240 if (fFoundFn)
241 {
242 int i;
243 /*
244 * Determin parameter description indent.
245 */
246 int cchMaxLen = 0;
247 for (i = 0; i < cArgs; i++)
248 {
249 _str sName, sType, sDefault;
250 if (!odin32_enumparams(sArgs, i, sType, sName, sDefault)
251 && cchMaxLen < length(sName))
252 cchMaxLen = length(sName);
253 }
254 cchMaxLen += length(" * @param ");
255 cchMaxLen = ((cchMaxLen + 2 + p_SyntaxIndent-1) intdiv p_SyntaxIndent) * p_SyntaxIndent;
256
257 /*
258 * Insert parameter.
259 */
260 for (i = 0; i < cArgs; i++)
261 {
262 _str sName, sType, sDefault;
263 if (!odin32_enumparams(sArgs, i, sType, sName, sDefault))
264 {
265 _insert_text(" * @param "sName"");
266 while (p_col <= cchMaxLen)
267 _insert_text(" ");
268 if (sDefault != "")
269 _insert_text("(default="sDefault")");
270 _insert_text("\n");
271 }
272 else
273 _insert_text(" * @param \n");
274 }
275 }
276 else
277 _insert_text(" * @param \n");
278 _insert_text(" * @equiv \n");
279 _insert_text(" * @time \n");
280 _insert_text(" * @sketch \n");
281 _insert_text(" * @status \n");
282 _insert_text(" * @author "sOdin32UserName" (" sOdin32UserEmail ")\n");
283 _insert_text(" * @remark \n");
284 _insert_text(" */\n");
285 up(9 + cArgs);
286 p_col = 4;
287 }
288}
289
290
291/**
292 *
293 * @remark defeventtab
294 */
295void odin32_globalbox()
296{
297 odin32_firstline("Global");
298 odin32_starlinestr(" Global Variables");
299 odin32_lastline();
300}
301
302
303void odin32_headerbox()
304{
305 odin32_firstline("Header");
306 odin32_starlinestr(" Header Files");
307 odin32_lastline();
308}
309
310
311void odin32_intfuncbox()
312{
313 odin32_firstline("IntFunc");
314 odin32_starlinestr(" Internal Functions");
315 odin32_lastline();
316}
317
318
319void odin32_constbox()
320{
321 odin32_firstline("Const");
322 odin32_starlinestr(" Defined Constants And Macros");
323 odin32_lastline();
324}
325
326
327void odin32_oneliner()
328{
329 end_line();
330 do
331 {
332 _insert_text(" ");
333 } while (p_col < 41);
334
335 if (file_eq(p_extension, 'asm'))
336 {
337 _insert_text("; ");
338 }
339 else
340 {
341 _insert_text("/* */");
342 p_col = p_col - 3;
343 }
344}
345
346
347void odin32_structbox()
348{
349 odin32_firstline("Struct");
350 odin32_starlinestr(" Structures and Typedefs");
351 odin32_lastline();
352}
353
354
355void odin32_modulebox()
356{
357 _begin_line();
358 if (file_eq(p_extension, 'asm'))
359 {
360 _insert_text("; $Id: odin32.e,v 1.10 2001-10-23 02:30:54 bird Exp $\n");
361 _insert_text("; \n");
362 _insert_text("; \n");
363 _insert_text("; \n");
364 _insert_text("; Copyright (c) " odin32_year() " "sOdin32UserName" (" sOdin32UserEmail ")\n");
365 _insert_text("; \n");
366 _insert_text("; Project Odin Software License can be found in LICENSE.TXT\n");
367 _insert_text("; \n");
368 up(6);
369 p_col = 3;
370 }
371 else
372 {
373 _insert_text("/* $Id: odin32.e,v 1.10 2001-10-23 02:30:54 bird Exp $\n");
374 _insert_text(" * \n");
375 _insert_text(" * \n");
376 _insert_text(" * \n");
377 _insert_text(" * Copyright (c) " odin32_year() " "sOdin32UserName" (" sOdin32UserEmail ")\n");
378 _insert_text(" *\n");
379 _insert_text(" * Project Odin Software License can be found in LICENSE.TXT\n");
380 _insert_text(" *\n");
381 _insert_text(" */\n");
382 up(7);
383 p_col = 4;
384 }
385}
386
387
388_command void odin32_maketagfile()
389{
390 /* We'll */
391 if (file_match('-p 'maybe_quote_filename(strip_filename(_project_name,'e'):+TAG_FILE_EXT),1)=="")
392 _project_update_files_retag(true,false,false,true);
393 else
394 _project_update_files_retag(false,false,false,false);
395}
396
397_command void odin32_setcurrentdir()
398{
399 //_ini_get_value(_project_name,"COMPILER","WORKINGDIR", workingdir);
400 //cd(workingdir);
401 /* Go the the directory containing the project filename */
402 cd(strip_filename(_project_name, 'NE'));
403}
404
405
406/**
407 * Hot-Key: Inserts a KLOGENTRY statement at start of nearest function.
408 */
409void odin32_klogentry()
410{
411 _save_pos2(org_pos);
412
413 /*
414 * Go to nearest function.
415 */
416 if (!odin32_func_goto_nearest())
417 {
418 /*
419 * Get parameters.
420 */
421 _str sParams = odin32_getparams();
422 if (sParams)
423 {
424 _str sRetType = odin32_getreturntype(true);
425 if (!sRetType || sRetType == "")
426 sRetType = "void"; /* paranoia! */
427
428 /*
429 * Insert text.
430 */
431 if (!odin32_searchcode("{"))
432 {
433 p_col++;
434 cArgs = odin32_countparams(sParams);
435 if (cArgs > 0)
436 {
437 sArgs = "";
438 for (i = 0; i < cArgs; i++)
439 {
440 _str sType, sName, sDefault
441 if (!odin32_enumparams(sParams, i, sType, sName, sDefault))
442 sArgs = sArgs', 'sName;
443 }
444
445 _insert_text("\n KLOGENTRY"cArgs"(\""sRetType"\",\""sParams"\""sArgs");"); /* todo tab size.. or smart indent */
446 }
447 else
448 _insert_text("\n KLOGENTRY0(\""sRetType"\");"); /* todo tab size.. or smart indent */
449
450 /*
451 * Check if the next word is KLOGENTRY.
452 */
453 next_word();
454 if (def_next_word_style == 'E')
455 prev_word();
456 if (substr(cur_word(iIgnorePos), 1, 9) == "KLOGENTRY")
457 delete_line();
458
459 }
460 else
461 message("didn't find {");
462 }
463 else
464 message("odin32_getparams failed, sParams=" sParams);
465 return;
466 }
467
468 _restore_pos2(org_pos);
469}
470
471
472/**
473 * Hot-Key: Inserts a KLOGEXIT statement at cursor location.
474 */
475void odin32_klogexit()
476{
477 _save_pos2(org_pos);
478
479 /*
480 * Go to nearest function.
481 */
482 if (!prev_proc())
483 {
484 /*
485 * Get parameters.
486 */
487 _str sType = odin32_getreturntype(true);
488 _restore_pos2(org_pos);
489 if (sType)
490 {
491 boolean fReturn = true; /* true if an return statment is following the KLOGEXIT statement. */
492
493 /*
494 * Insert text.
495 */
496 cur_col = p_col;
497 if (sType == 'void' || sType == 'VOID')
498 { /* procedure */
499 fReturn = cur_word(iIgnorePos) == 'return';
500 if (!fReturn)
501 {
502 while (p_col <= p_SyntaxIndent)
503 keyin(" ");
504 }
505
506 _insert_text("KLOGEXITVOID();\n");
507
508 if (fReturn)
509 {
510 for (i = 1; i < cur_col; i++)
511 _insert_text(" ");
512 }
513 search(")","E-");
514 }
515 else
516 { /* function */
517 _insert_text("KLOGEXIT();\n");
518 for (i = 1; i < cur_col; i++)
519 _insert_text(" ");
520 search(")","E-");
521
522 /*
523 * Insert value if possible.
524 */
525 _save_pos2(valuepos);
526 next_word();
527 if (def_next_word_style == 'E')
528 prev_word();
529 if (cur_word(iIgnorePos) == 'return')
530 {
531 p_col += length('return');
532 _save_pos2(posStart);
533 offStart = _QROffset();
534 if (!odin32_searchcode(";", "E+"))
535 {
536 offEnd = _QROffset();
537 _restore_pos2(posStart);
538 _str sValue = strip(get_text(offEnd - offStart));
539 //say 'sValue = 'sValue;
540 _restore_pos2(valuepos);
541 _save_pos2(valuepos);
542 _insert_text(sValue);
543 }
544 }
545 _restore_pos2(valuepos);
546 }
547
548 /*
549 * Remove old KLOGEXIT statement on previous line if any.
550 */
551 _save_pos2(valuepos);
552 newexitline = p_line;
553 p_line--; p_col = 1;
554 next_word();
555 if (def_next_word_style == 'E')
556 prev_word();
557 if (p_line == newexitline - 1 && substr(cur_word(iIgnorePos), 1, 8) == 'KLOGEXIT')
558 delete_line();
559 _restore_pos2(valuepos);
560
561 /*
562 * Check for missing '{...}'.
563 */
564 if (fReturn)
565 {
566 boolean fFound = false;
567 _save_pos2(valuepos);
568 p_col--; find_matching_paren(); p_col += 2;
569 odin32_searchcode(';', 'E+'); /* places us at the ';' of the return. (hopefully) */
570
571 _str ch = odin32_get_next_code_text();
572 if (ch != '}')
573 {
574 _restore_pos2(valuepos);
575 _save_pos2(valuepos);
576 p_col--; find_matching_paren(); p_col += 2;
577 odin32_searchcode(';', 'E+'); /* places us at the ';' of the return. (hopefully) */
578 p_col++;
579 if (odin32_more_code_on_line())
580 _insert_text(' }');
581 else
582 {
583 _save_pos2(returnget);
584 odin32_searchcode("return", "E-");
585 return_col = p_col;
586 _restore_pos2(returnget);
587
588 end_line();
589 _insert_text("\n");
590 while (p_col < return_col - p_SyntaxIndent)
591 _insert_text(' ');
592 _insert_text('}');
593 }
594
595 _restore_pos2(valuepos);
596 _save_pos2(valuepos);
597 prev_word();
598 p_col -= p_SyntaxIndent;
599 codecol = p_col;
600 _insert_text("{\n");
601 while (p_col < codecol)
602 _insert_text(' ');
603 }
604
605 _restore_pos2(valuepos);
606 }
607 }
608 else
609 message("odin32_getreturntype failed, sType=" sType);
610 return;
611 }
612
613 _restore_pos2(org_pos);
614}
615
616
617/**
618 * Processes a file - ask user all the time.
619 */
620void odin32_klog_file_ask()
621{
622 odin32_klog_file_int(true)
623}
624
625
626/**
627 * Processes a file - no questions.
628 */
629void odin32_klog_file_no_ask()
630{
631 odin32_klog_file_int(false)
632}
633
634
635
636/**
637 * Processes a file.
638 */
639static void odin32_klog_file_int(boolean fAsk)
640{
641 show_all();
642 bottom();
643 _refresh_scroll();
644
645 /* ask question so we can get to the right position somehow.. */
646 if (fAsk && _message_box("kLog process this file?", "Visual SlickEdit", MB_YESNO | MB_ICONQUESTION) != IDYES)
647 return;
648
649 /*
650 * Entries.
651 */
652 while (!prev_proc())
653 {
654 //say 'entry main loop: ' odin32_getfunction();
655
656 /*
657 * Skip prototypes.
658 */
659 if (odin32_prototype())
660 continue;
661
662 /*
663 * Ask user.
664 */
665 center_line();
666 _refresh_scroll();
667 sFunction = odin32_getfunction();
668 rc = fAsk ? _message_box("Process this function ("sFunction")?", "Visual SlickEdit", MB_YESNOCANCEL | MB_ICONQUESTION) : IDYES;
669 if (rc == IDYES)
670 {
671 _save_pos2(procpos);
672 odin32_klogentry();
673 _restore_pos2(procpos);
674 }
675 else if (rc == IDNO)
676 continue;
677 else
678 break;
679 }
680
681 /*
682 * Exits.
683 */
684 bottom(); _refresh_scroll();
685 boolean fUserCancel = false;
686 while (!prev_proc() && !fUserCancel)
687 {
688 _save_pos2(procpos);
689 sCurFunction = odin32_getfunction();
690 //say 'exit main loop: ' sCurFunction
691
692 /*
693 * Skip prototypes.
694 */
695 if (odin32_prototype())
696 continue;
697
698 /*
699 * Select procedure.
700 */
701 while ( !odin32_searchcode("return", "WE<+")
702 && odin32_getfunction() == sCurFunction)
703 {
704 //say 'exit sub loop: ' p_line
705 /*
706 * Ask User.
707 */
708 center_line();
709 _refresh_scroll();
710 sFunction = odin32_getfunction();
711 rc = fAsk ? _message_box("Process this exit from "sFunction"?", "Visual SlickEdit", MB_YESNOCANCEL | MB_ICONQUESTION) : IDYES;
712 deselect();
713 if (rc == IDYES)
714 {
715 _save_pos2(returnpos);
716 odin32_klogexit();
717 _restore_pos2(returnpos);
718 p_line++;
719 }
720 else if (rc != IDNO)
721 {
722 fUserCancel = true;
723 break;
724 }
725 p_line++; /* just so we won't hit it again. */
726 }
727
728 /*
729 * If void function we'll have to check if there is and return; prior to the ending '}'.
730 */
731 _restore_pos2(procpos);
732 _save_pos2(procpos);
733 sType = odin32_getreturntype(true);
734 if (!fUserCancel && sType && (sType == 'void' || sType == 'VOID'))
735 {
736 if ( !odin32_searchcode("{", "E+")
737 && !find_matching_paren())
738 {
739 _save_pos2(funcend);
740 prev_word();
741 if (cur_word(iIgnorePos) != "return")
742 {
743 /*
744 * Ask User.
745 */
746 _restore_pos2(funcend);
747 center_line();
748 _refresh_scroll();
749 sFunction = odin32_getfunction();
750 rc = fAsk ? _message_box("Process this exit from "sFunction"?", "Visual SlickEdit", MB_YESNOCANCEL | MB_ICONQUESTION) : IDYES;
751 deselect();
752 if (rc == IDYES)
753 {
754 _save_pos2(returnpos);
755 odin32_klogexit();
756 _restore_pos2(returnpos);
757 }
758 }
759 }
760 }
761
762 /*
763 * Next proc.
764 */
765 _restore_pos2(procpos);
766 }
767
768
769}
770
771
772/**
773 * Moves cursor to nearest function start.
774 */
775int odin32_func_goto_nearest()
776{
777 cur_line = p_line;
778 prev_line = -1;
779 next_line = -1;
780 _save_pos2(org_pos);
781
782 if (!next_proc(1))
783 {
784 next_line = p_line;
785 if (!prev_proc(1) && p_line == cur_line)
786 {
787 _restore_pos2(org_pos);
788 return 0;
789 }
790 _restore_pos2(org_pos);
791 _save_pos2(org_pos);
792 }
793 else
794 p_col++; /* fixes problem with single function files. */
795
796 if (!prev_proc(1))
797 {
798 prev_line = p_line;
799 if (!next_proc(1) && p_line == cur_line)
800 {
801 _restore_pos2(org_pos);
802 return 0;
803 }
804 _restore_pos2(org_pos);
805 _save_pos2(org_pos);
806 }
807
808
809 if (prev_line != -1 && (next_line == -1 || cur_line - prev_line <= next_line - cur_line))
810 {
811 prev_proc(1);
812 return 0;
813 }
814
815 if (next_line != -1 && (prev_line == -1 || cur_line - prev_line > next_line - cur_line))
816 {
817 next_proc();
818 return 0;
819 }
820
821 _restore_pos2(org_pos);
822 return -1;
823}
824
825
826/**
827 * Check if nearest function is a prototype.
828 */
829boolean odin32_prototype()
830{
831 /*
832 * Check if this is a real function implementation.
833 */
834 _save_pos2(procpos);
835 if (!odin32_func_goto_nearest())
836 {
837 proc_line = p_line;
838
839 if (!odin32_searchcode("{"))
840 {
841 prev_proc();
842 if (p_line != proc_line)
843 {
844 _restore_pos2(procpos);
845 return true;
846 }
847 }
848 }
849 _restore_pos2(procpos);
850
851 return false;
852}
853
854
855/**
856 * Gets the name fo the current function.
857 */
858static _str odin32_getfunction()
859{
860 sFunctionName = current_proc();
861 if (!sFunctionName)
862 sFunctionName == "";
863 //say 'functionanme='sFunctionName;
864 return sFunctionName;
865}
866
867
868/**
869 * Goes to the neares function and gets its parameters.
870 * @remark Should be reimplemented to use tags (if someone can figure out how to query that stuff).
871 */
872static _str odin32_getparams()
873{
874 _save_pos2(org_pos);
875
876 /*
877 * Go to nearest function.
878 */
879 if ( !odin32_func_goto_nearest()
880 && !odin32_searchcode("(") /* makes some assumptions. */
881 )
882 {
883 /*
884 * Get parameters.
885 */
886 _save_pos2(posStart);
887 offStart = _QROffset();
888 if (!find_matching_paren())
889 {
890 offEnd = _QROffset();
891 _restore_pos2(posStart);
892 p_col++;
893 _str sParamsRaw = strip(get_text(offEnd - offStart - 1));
894
895
896 /*
897 * Remove new lines and double spaces within params.
898 */
899 _str sParams = "";
900
901 int i;
902 for (i = 1, chPrev = ' '; i <= length(sParamsRaw); i++)
903 {
904 ch = substr(sParamsRaw, i, 1);
905
906 /*
907 * Do fixups.
908 */
909 if (ch == " " && chPrev == " ")
910 continue;
911
912 if ((ch :== "\n") || (ch :== "\r") || (ch :== "\t"))
913 {
914 if (chPrev == ' ')
915 continue;
916 ch = ' ';
917 }
918
919 if (ch == ',' && chPrev == ' ')
920 {
921 sParams = substr(sParams, 1, length(sParams) - 1);
922 }
923
924 if (ch == '*')
925 {
926 if (chPrev != ' ')
927 sParams = sParams :+ ' * ';
928 else
929 sParams = sParams :+ '* ';
930 chPrev = ' ';
931 }
932 else
933 {
934 sParams = sParams :+ ch;
935 chPrev = ch;
936 }
937
938 } /* for */
939
940 sParams = strip(sParams);
941 if (sParams == 'void' || sParams == 'VOID')
942 sParams = "";
943 _restore_pos2(org_pos);
944 return sParams;
945 }
946 else
947 message("find_matchin_paren failed");
948 }
949
950 _restore_pos2(org_pos);
951 return false;
952}
953
954
955
956/**
957 * Enumerates the parameters to the function.
958 * @param sParams Parameter string from odin32_getparams.
959 * @param iParam The index (0-based) of the parameter to get.
960 * @param sType Type. (output)
961 * @param sName Name. (output)
962 * @param sDefault Default value. (output)
963 * @remark Doesn't perhaps handle function pointers very well (I think)?
964 * @remark Should be reimplemented to use tags (if someone can figure out how to query that stuff).
965 */
966static int odin32_enumparams(_str sParams, int iParam, _str &sType, _str &sName, _str &sDefault)
967{
968 int i;
969 int iParLevel;
970 int iCurParam;
971 int iStartParam;
972
973 sType = sName = sDefault = "";
974
975 /* no use working on empty string! */
976 if (length(sParams) == 0)
977 return -1;
978
979 /* find the parameter in question */
980 for (iStartParam = i = 1, iParLevel = iCurParam = 0; i <= length(sParams); i++)
981 {
982 _str ch = substr(sParams, i, 1);
983 if (ch == ',' && iParLevel == 0)
984 {
985 /* is it this parameter ? */
986 if (iParam == iCurParam)
987 break;
988
989 iCurParam++;
990 iStartParam = i + 1;
991 }
992 else if (ch == '(')
993 iParLevel++;
994 else if (ch == ')')
995 iParLevel--;
996 }
997
998 /* did we find the parameter? */
999 if (iParam == iCurParam)
1000 { /* (yeah, we did!) */
1001 sArg = strip(substr(sParams, iStartParam, i - iStartParam));
1002
1003 /* lazy approach, which doens't support function types */
1004
1005 if (pos('=', sParams) > 0) /* default */
1006 {
1007 sDefault = strip(substr(sParams, pos('=', sParams) + 1));
1008 sArg = strip(substr(sArg, 1, pos('=', sParams) - 1));
1009 }
1010
1011 for (i = length(sArg); i > 1; i--)
1012 {
1013 _str ch = substr(sArg, i, 1);
1014 if ( !(ch >= 'a' && ch <= 'z')
1015 && !(ch >= 'A' && ch <= 'Z')
1016 && !(ch >= '0' && ch <= '9')
1017 && ch != '_' && ch != '$')
1018 break;
1019 }
1020 if (sArg == "...")
1021 i = 0;
1022 sName = strip(substr(sArg, i + 1));
1023 sType = strip(substr(sArg, 1, i));
1024
1025 return 0;
1026 }
1027
1028 return -1;
1029}
1030
1031
1032/**
1033 * Counts the parameters to the function.
1034 * @param sParams Parameter string from odin32_getparams.
1035 * @remark Should be reimplemented to use tags (if someone can figure out how to query that stuff).
1036 */
1037static int odin32_countparams(_str sParams)
1038{
1039 int i;
1040 int iParLevel;
1041 int iCurParam;
1042
1043 sType = sName = sDefault = "";
1044
1045 /* check for 0 parameters */
1046 if (length(sParams) == 0)
1047 return 0;
1048
1049 /* find the parameter in question */
1050 for (i = 1, iParLevel = iCurParam = 0; i <= length(sParams); i++)
1051 {
1052 _str ch = substr(sParams, i, 1);
1053 if (ch == ',' && iParLevel == 0)
1054 {
1055 iCurParam++;
1056 }
1057 else if (ch == '(')
1058 iParLevel++;
1059 else if (ch == ')')
1060 iParLevel--;
1061 }
1062
1063 return iCurParam + 1;
1064}
1065
1066/**
1067 * Gets the return type.
1068 */
1069static _str odin32_getreturntype(boolean fPureType = false)
1070{
1071 _save_pos2(org_pos);
1072
1073 /*
1074 * Go to nearest function.
1075 */
1076 if (!odin32_func_goto_nearest())
1077 {
1078 /*
1079 * Return type is from function start to function name...
1080 */
1081 _save_pos2(posStart);
1082 offStart = _QROffset();
1083
1084 if (!odin32_searchcode("(")) /* makes some assumptions. */
1085 {
1086 prev_word();
1087 offEnd = _QROffset();
1088 _restore_pos2(posStart);
1089 _str sTypeRaw = strip(get_text(offEnd - offStart));
1090
1091 //say 'sTypeRaw='sTypeRaw;
1092 /*
1093 * Remove static, inline, _Optlink, stdcall, EXPENTRY etc.
1094 */
1095 if (fPureType)
1096 {
1097 sTypeRaw = stranslate(sTypeRaw, "", "__static__", "I");
1098 sTypeRaw = stranslate(sTypeRaw, "", "__static", "I");
1099 sTypeRaw = stranslate(sTypeRaw, "", "static__", "I");
1100 sTypeRaw = stranslate(sTypeRaw, "", "static", "I");
1101 sTypeRaw = stranslate(sTypeRaw, "", "__inline__", "I");
1102 sTypeRaw = stranslate(sTypeRaw, "", "__inline", "I");
1103 sTypeRaw = stranslate(sTypeRaw, "", "inline__", "I");
1104 sTypeRaw = stranslate(sTypeRaw, "", "inline", "I");
1105 sTypeRaw = stranslate(sTypeRaw, "", "EXPENTRY", "I");
1106 sTypeRaw = stranslate(sTypeRaw, "", "_Optlink", "I");
1107 sTypeRaw = stranslate(sTypeRaw, "", "__stdcall", "I");
1108 sTypeRaw = stranslate(sTypeRaw, "", "__cdecl", "I");
1109 sTypeRaw = stranslate(sTypeRaw, "", "_cdecl", "I");
1110 sTypeRaw = stranslate(sTypeRaw, "", "cdecl", "I");
1111 sTypeRaw = stranslate(sTypeRaw, "", "PASCAL", "I");
1112 sTypeRaw = stranslate(sTypeRaw, "", "__far", "I");
1113 sTypeRaw = stranslate(sTypeRaw, "", "_far", "I");
1114 sTypeRaw = stranslate(sTypeRaw, "", "far", "I");
1115 sTypeRaw = stranslate(sTypeRaw, "", "__near", "I");
1116 sTypeRaw = stranslate(sTypeRaw, "", "_near", "I");
1117 sTypeRaw = stranslate(sTypeRaw, "", "near", "I");
1118 sTypeRaw = stranslate(sTypeRaw, "", "WIN32API", "I");
1119 sTypeRaw = stranslate(sTypeRaw, "", "WINAPI", "I");
1120 sTypeRaw = stranslate(sTypeRaw, "", "__operator__", "I"); /* operator fix */
1121 sTypeRaw = stranslate(sTypeRaw, "", "__operator", "I"); /* operator fix */
1122 sTypeRaw = stranslate(sTypeRaw, "", "operator__", "I"); /* operator fix */
1123 sTypeRaw = stranslate(sTypeRaw, "", "operator", "I"); /* operator fix */
1124 }
1125
1126 /*
1127 * Remove new lines and double spaces within params.
1128 */
1129 _str sType = "";
1130
1131 int i;
1132 for (i = 1, chPrev = ' '; i <= length(sTypeRaw); i++)
1133 {
1134 ch = substr(sTypeRaw, i, 1);
1135
1136 /*
1137 * Do fixups.
1138 */
1139 if (ch == " " && chPrev == " ")
1140 continue;
1141
1142 if ((ch :== "\n") || (ch :== "\r") || (ch :== "\t"))
1143 {
1144 if (chPrev == ' ')
1145 continue;
1146 ch = ' ';
1147 }
1148
1149 if (ch == ',' && chPrev == ' ')
1150 {
1151 sType = substr(sType, 1, length(sType) - 1);
1152 }
1153
1154 if (ch == '*')
1155 {
1156 if (chPrev != ' ')
1157 sType = sType :+ ' * ';
1158 else
1159 sType = sType :+ '* ';
1160 chPrev = ' ';
1161 }
1162 else
1163 {
1164 sType = sType :+ ch;
1165 chPrev = ch;
1166 }
1167
1168 } /* for */
1169
1170 sType = strip(sType);
1171
1172 _restore_pos2(org_pos);
1173 return sType;
1174 }
1175 else
1176 message('odin32_getreturntype: can''t find ''(''.');
1177 }
1178
1179 _restore_pos2(org_pos);
1180 return false;
1181}
1182
1183
1184/**
1185 * Search for some piece of code.
1186 */
1187static int odin32_searchcode(_str sSearchString, _str sOptions = "E+")
1188{
1189 int rc;
1190 rc = search(sSearchString, sOptions);
1191 while (!rc && !odin32_in_code())
1192 {
1193 p_col++;
1194 rc = search(sSearchString, sOptions);
1195 }
1196 return rc;
1197}
1198
1199
1200/**
1201 * Checks if cursor is in code or in comment.
1202 */
1203static boolean odin32_in_code()
1204{
1205 _save_pos2(searchsave);
1206 boolean fRc = !_in_comment();
1207 _restore_pos2(searchsave);
1208 return fRc;
1209}
1210
1211
1212/*
1213 * Gets the next piece of code.
1214 */
1215static _str odin32_get_next_code_text()
1216{
1217 _str ch;
1218 _save_pos2(searchsave);
1219 ch = odin32_get_next_code_text2();
1220 _restore_pos2(searchsave);
1221 return ch;
1222}
1223
1224
1225/**
1226 * Checks if there is more code on the line.
1227 */
1228static boolean odin32_more_code_on_line()
1229{
1230 boolean fRc;
1231 int curline = p_line;
1232
1233 _save_pos2(searchsave);
1234 odin32_get_next_code_text2();
1235 fRc = curline == p_line;
1236 _restore_pos2(searchsave);
1237
1238 return fRc;
1239}
1240
1241
1242/**
1243 * Gets the next piece of code.
1244 * Doesn't preserver cursor position.
1245 */
1246static _str odin32_get_next_code_text2()
1247{
1248 _str ch;
1249 do
1250 {
1251 curcol = ++p_col;
1252 end_line()
1253 if (p_col <= curcol)
1254 {
1255 p_line++;
1256 p_col = 1;
1257 }
1258 else
1259 p_col = curcol;
1260
1261 ch = get_text();
1262 //say ch ' ('_asc(ch)')';
1263 while (ch == "#") /* preprocessor stuff */
1264 {
1265 p_col = 1;
1266 p_line++;
1267 ch = get_text();
1268 //say ch ' ('_asc(ch)')';
1269 continue;
1270 }
1271 } while (ch :== ' ' || ch :== "\t" || ch :== "\n" || ch :== "\r" || !odin32_in_code());
1272
1273 return ch;
1274}
1275
Note: See TracBrowser for help on using the repository browser.