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

Last change on this file since 10367 was 7436, checked in by bird, 24 years ago

Changed my mail address.

File size: 34.5 KB
Line 
1/* $Id: odin32.e,v 1.13 2001-11-23 01:04:35 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 = "kosmunds@csc.com";
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.13 2001-11-23 01:04:35 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.13 2001-11-23 01:04:35 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 boolean fFix = false; /* cursor at function fix. (last function) */
778 cur_line = p_line;
779 prev_line = -1;
780 next_line = -1;
781 _save_pos2(org_pos);
782
783 if (!next_proc(1))
784 {
785 next_line = p_line;
786 if (!prev_proc(1) && p_line == cur_line)
787 {
788 _restore_pos2(org_pos);
789 return 0;
790 }
791 _restore_pos2(org_pos);
792 _save_pos2(org_pos);
793 }
794 else
795 {
796 p_col++; /* fixes problem with single function files. */
797 fFix = true;
798 }
799
800 if (!prev_proc(1))
801 {
802 prev_line = p_line;
803 if (!next_proc(1) && p_line == cur_line)
804 {
805 _restore_pos2(org_pos);
806 return 0;
807 }
808 _restore_pos2(org_pos);
809 _save_pos2(org_pos);
810 }
811
812
813 if (prev_line != -1 && (next_line == -1 || cur_line - prev_line <= next_line - cur_line))
814 {
815 if (fFix)
816 p_col++;
817 prev_proc(1);
818 return 0;
819 }
820
821 if (next_line != -1 && (prev_line == -1 || cur_line - prev_line > next_line - cur_line))
822 {
823 next_proc();
824 return 0;
825 }
826
827 _restore_pos2(org_pos);
828 return -1;
829}
830
831
832/**
833 * Check if nearest function is a prototype.
834 */
835boolean odin32_prototype()
836{
837 /*
838 * Check if this is a real function implementation.
839 */
840 _save_pos2(procpos);
841 if (!odin32_func_goto_nearest())
842 {
843 proc_line = p_line;
844
845 if (!odin32_searchcode("{"))
846 {
847 prev_proc();
848 if (p_line != proc_line)
849 {
850 _restore_pos2(procpos);
851 return true;
852 }
853 }
854 }
855 _restore_pos2(procpos);
856
857 return false;
858}
859
860
861/**
862 * Gets the name fo the current function.
863 */
864static _str odin32_getfunction()
865{
866 sFunctionName = current_proc();
867 if (!sFunctionName)
868 sFunctionName == "";
869 //say 'functionanme='sFunctionName;
870 return sFunctionName;
871}
872
873
874/**
875 * Goes to the neares function and gets its parameters.
876 * @remark Should be reimplemented to use tags (if someone can figure out how to query that stuff).
877 */
878static _str odin32_getparams()
879{
880 _save_pos2(org_pos);
881
882 /*
883 * Go to nearest function.
884 */
885 if ( !odin32_func_goto_nearest()
886 && !odin32_searchcode("(") /* makes some assumptions. */
887 )
888 {
889 /*
890 * Get parameters.
891 */
892 _save_pos2(posStart);
893 offStart = _QROffset();
894 if (!find_matching_paren())
895 {
896 offEnd = _QROffset();
897 _restore_pos2(posStart);
898 p_col++;
899 _str sParamsRaw = strip(get_text(offEnd - offStart - 1));
900
901
902 /*
903 * Remove new lines and double spaces within params.
904 */
905 _str sParams = "";
906
907 int i;
908 for (i = 1, chPrev = ' '; i <= length(sParamsRaw); i++)
909 {
910 ch = substr(sParamsRaw, i, 1);
911
912 /*
913 * Do fixups.
914 */
915 if (ch == " " && chPrev == " ")
916 continue;
917
918 if ((ch :== "\n") || (ch :== "\r") || (ch :== "\t"))
919 {
920 if (chPrev == ' ')
921 continue;
922 ch = ' ';
923 }
924
925 if (ch == ',' && chPrev == ' ')
926 {
927 sParams = substr(sParams, 1, length(sParams) - 1);
928 }
929
930 if (ch == '*')
931 {
932 if (chPrev != ' ')
933 sParams = sParams :+ ' * ';
934 else
935 sParams = sParams :+ '* ';
936 chPrev = ' ';
937 }
938 else
939 {
940 sParams = sParams :+ ch;
941 chPrev = ch;
942 }
943
944 } /* for */
945
946 sParams = strip(sParams);
947 if (sParams == 'void' || sParams == 'VOID')
948 sParams = "";
949 _restore_pos2(org_pos);
950 return sParams;
951 }
952 else
953 message("find_matchin_paren failed");
954 }
955
956 _restore_pos2(org_pos);
957 return false;
958}
959
960
961
962/**
963 * Enumerates the parameters to the function.
964 * @param sParams Parameter string from odin32_getparams.
965 * @param iParam The index (0-based) of the parameter to get.
966 * @param sType Type. (output)
967 * @param sName Name. (output)
968 * @param sDefault Default value. (output)
969 * @remark Doesn't perhaps handle function pointers very well (I think)?
970 * @remark Should be reimplemented to use tags (if someone can figure out how to query that stuff).
971 */
972static int odin32_enumparams(_str sParams, int iParam, _str &sType, _str &sName, _str &sDefault)
973{
974 int i;
975 int iParLevel;
976 int iCurParam;
977 int iStartParam;
978
979 sType = sName = sDefault = "";
980
981 /* no use working on empty string! */
982 if (length(sParams) == 0)
983 return -1;
984
985 /* find the parameter in question */
986 for (iStartParam = i = 1, iParLevel = iCurParam = 0; i <= length(sParams); i++)
987 {
988 _str ch = substr(sParams, i, 1);
989 if (ch == ',' && iParLevel == 0)
990 {
991 /* is it this parameter ? */
992 if (iParam == iCurParam)
993 break;
994
995 iCurParam++;
996 iStartParam = i + 1;
997 }
998 else if (ch == '(')
999 iParLevel++;
1000 else if (ch == ')')
1001 iParLevel--;
1002 }
1003
1004 /* did we find the parameter? */
1005 if (iParam == iCurParam)
1006 { /* (yeah, we did!) */
1007 sArg = strip(substr(sParams, iStartParam, i - iStartParam));
1008
1009 /* lazy approach, which doens't support function types */
1010
1011 if (pos('=', sParams) > 0) /* default */
1012 {
1013 sDefault = strip(substr(sParams, pos('=', sParams) + 1));
1014 sArg = strip(substr(sArg, 1, pos('=', sParams) - 1));
1015 }
1016
1017 for (i = length(sArg); i > 1; i--)
1018 {
1019 _str ch = substr(sArg, i, 1);
1020 if ( !(ch >= 'a' && ch <= 'z')
1021 && !(ch >= 'A' && ch <= 'Z')
1022 && !(ch >= '0' && ch <= '9')
1023 && ch != '_' && ch != '$')
1024 break;
1025 }
1026 if (sArg == "...")
1027 i = 0;
1028 sName = strip(substr(sArg, i + 1));
1029 sType = strip(substr(sArg, 1, i));
1030
1031 return 0;
1032 }
1033
1034 return -1;
1035}
1036
1037
1038/**
1039 * Counts the parameters to the function.
1040 * @param sParams Parameter string from odin32_getparams.
1041 * @remark Should be reimplemented to use tags (if someone can figure out how to query that stuff).
1042 */
1043static int odin32_countparams(_str sParams)
1044{
1045 int i;
1046 int iParLevel;
1047 int iCurParam;
1048
1049 sType = sName = sDefault = "";
1050
1051 /* check for 0 parameters */
1052 if (length(sParams) == 0)
1053 return 0;
1054
1055 /* find the parameter in question */
1056 for (i = 1, iParLevel = iCurParam = 0; i <= length(sParams); i++)
1057 {
1058 _str ch = substr(sParams, i, 1);
1059 if (ch == ',' && iParLevel == 0)
1060 {
1061 iCurParam++;
1062 }
1063 else if (ch == '(')
1064 iParLevel++;
1065 else if (ch == ')')
1066 iParLevel--;
1067 }
1068
1069 return iCurParam + 1;
1070}
1071
1072/**
1073 * Gets the return type.
1074 */
1075static _str odin32_getreturntype(boolean fPureType = false)
1076{
1077 _save_pos2(org_pos);
1078
1079 /*
1080 * Go to nearest function.
1081 */
1082 if (!odin32_func_goto_nearest())
1083 {
1084 /*
1085 * Return type is from function start to function name...
1086 */
1087 _save_pos2(posStart);
1088 offStart = _QROffset();
1089
1090 if (!odin32_searchcode("(")) /* makes some assumptions. */
1091 {
1092 prev_word();
1093 offEnd = _QROffset();
1094 _restore_pos2(posStart);
1095 _str sTypeRaw = strip(get_text(offEnd - offStart));
1096
1097 //say 'sTypeRaw='sTypeRaw;
1098 /*
1099 * Remove static, inline, _Optlink, stdcall, EXPENTRY etc.
1100 */
1101 if (fPureType)
1102 {
1103 sTypeRaw = stranslate(sTypeRaw, "", "__static__", "I");
1104 sTypeRaw = stranslate(sTypeRaw, "", "__static", "I");
1105 sTypeRaw = stranslate(sTypeRaw, "", "static__", "I");
1106 sTypeRaw = stranslate(sTypeRaw, "", "static", "I");
1107 sTypeRaw = stranslate(sTypeRaw, "", "__inline__", "I");
1108 sTypeRaw = stranslate(sTypeRaw, "", "__inline", "I");
1109 sTypeRaw = stranslate(sTypeRaw, "", "inline__", "I");
1110 sTypeRaw = stranslate(sTypeRaw, "", "inline", "I");
1111 sTypeRaw = stranslate(sTypeRaw, "", "EXPENTRY", "I");
1112 sTypeRaw = stranslate(sTypeRaw, "", "_Optlink", "I");
1113 sTypeRaw = stranslate(sTypeRaw, "", "__stdcall", "I");
1114 sTypeRaw = stranslate(sTypeRaw, "", "__cdecl", "I");
1115 sTypeRaw = stranslate(sTypeRaw, "", "_cdecl", "I");
1116 sTypeRaw = stranslate(sTypeRaw, "", "cdecl", "I");
1117 sTypeRaw = stranslate(sTypeRaw, "", "__PASCAL", "I");
1118 sTypeRaw = stranslate(sTypeRaw, "", "_PASCAL", "I");
1119 sTypeRaw = stranslate(sTypeRaw, "", "PASCAL", "I");
1120 sTypeRaw = stranslate(sTypeRaw, "", "__Far32__", "I");
1121 sTypeRaw = stranslate(sTypeRaw, "", "__Far32", "I");
1122 sTypeRaw = stranslate(sTypeRaw, "", "Far32__", "I");
1123 sTypeRaw = stranslate(sTypeRaw, "", "_Far32_", "I");
1124 sTypeRaw = stranslate(sTypeRaw, "", "_Far32", "I");
1125 sTypeRaw = stranslate(sTypeRaw, "", "Far32_", "I");
1126 sTypeRaw = stranslate(sTypeRaw, "", "Far32", "I");
1127 sTypeRaw = stranslate(sTypeRaw, "", "__far", "I");
1128 sTypeRaw = stranslate(sTypeRaw, "", "_far", "I");
1129 sTypeRaw = stranslate(sTypeRaw, "", "far", "I");
1130 sTypeRaw = stranslate(sTypeRaw, "", "__near", "I");
1131 sTypeRaw = stranslate(sTypeRaw, "", "_near", "I");
1132 sTypeRaw = stranslate(sTypeRaw, "", "near", "I");
1133 sTypeRaw = stranslate(sTypeRaw, "", "__loadds__", "I");
1134 sTypeRaw = stranslate(sTypeRaw, "", "__loadds", "I");
1135 sTypeRaw = stranslate(sTypeRaw, "", "loadds__", "I");
1136 sTypeRaw = stranslate(sTypeRaw, "", "_loadds_", "I");
1137 sTypeRaw = stranslate(sTypeRaw, "", "_loadds", "I");
1138 sTypeRaw = stranslate(sTypeRaw, "", "loadds_", "I");
1139 sTypeRaw = stranslate(sTypeRaw, "", "loadds", "I");
1140 sTypeRaw = stranslate(sTypeRaw, "", "__loades__", "I");
1141 sTypeRaw = stranslate(sTypeRaw, "", "__loades", "I");
1142 sTypeRaw = stranslate(sTypeRaw, "", "loades__", "I");
1143 sTypeRaw = stranslate(sTypeRaw, "", "_loades_", "I");
1144 sTypeRaw = stranslate(sTypeRaw, "", "_loades", "I");
1145 sTypeRaw = stranslate(sTypeRaw, "", "loades_", "I");
1146 sTypeRaw = stranslate(sTypeRaw, "", "loades", "I");
1147 sTypeRaw = stranslate(sTypeRaw, "", "WIN32API", "I");
1148 sTypeRaw = stranslate(sTypeRaw, "", "WINAPI", "I");
1149 sTypeRaw = stranslate(sTypeRaw, "", "LDRCALL", "I");
1150 sTypeRaw = stranslate(sTypeRaw, "", "KRNLCALL", "I");
1151 sTypeRaw = stranslate(sTypeRaw, "", "__operator__", "I"); /* operator fix */
1152 sTypeRaw = stranslate(sTypeRaw, "", "__operator", "I"); /* operator fix */
1153 sTypeRaw = stranslate(sTypeRaw, "", "operator__", "I"); /* operator fix */
1154 sTypeRaw = stranslate(sTypeRaw, "", "operator", "I"); /* operator fix */
1155 }
1156
1157 /*
1158 * Remove new lines and double spaces within params.
1159 */
1160 _str sType = "";
1161
1162 int i;
1163 for (i = 1, chPrev = ' '; i <= length(sTypeRaw); i++)
1164 {
1165 ch = substr(sTypeRaw, i, 1);
1166
1167 /*
1168 * Do fixups.
1169 */
1170 if (ch == " " && chPrev == " ")
1171 continue;
1172
1173 if ((ch :== "\n") || (ch :== "\r") || (ch :== "\t"))
1174 {
1175 if (chPrev == ' ')
1176 continue;
1177 ch = ' ';
1178 }
1179
1180 if (ch == ',' && chPrev == ' ')
1181 {
1182 sType = substr(sType, 1, length(sType) - 1);
1183 }
1184
1185 if (ch == '*')
1186 {
1187 if (chPrev != ' ')
1188 sType = sType :+ ' * ';
1189 else
1190 sType = sType :+ '* ';
1191 chPrev = ' ';
1192 }
1193 else
1194 {
1195 sType = sType :+ ch;
1196 chPrev = ch;
1197 }
1198
1199 } /* for */
1200
1201 sType = strip(sType);
1202
1203 _restore_pos2(org_pos);
1204 return sType;
1205 }
1206 else
1207 message('odin32_getreturntype: can''t find ''(''.');
1208 }
1209
1210 _restore_pos2(org_pos);
1211 return false;
1212}
1213
1214
1215/**
1216 * Search for some piece of code.
1217 */
1218static int odin32_searchcode(_str sSearchString, _str sOptions = "E+")
1219{
1220 int rc;
1221 rc = search(sSearchString, sOptions);
1222 while (!rc && !odin32_in_code())
1223 {
1224 p_col++;
1225 rc = search(sSearchString, sOptions);
1226 }
1227 return rc;
1228}
1229
1230
1231/**
1232 * Checks if cursor is in code or in comment.
1233 */
1234static boolean odin32_in_code()
1235{
1236 _save_pos2(searchsave);
1237 boolean fRc = !_in_comment();
1238 _restore_pos2(searchsave);
1239 return fRc;
1240}
1241
1242
1243/*
1244 * Gets the next piece of code.
1245 */
1246static _str odin32_get_next_code_text()
1247{
1248 _str ch;
1249 _save_pos2(searchsave);
1250 ch = odin32_get_next_code_text2();
1251 _restore_pos2(searchsave);
1252 return ch;
1253}
1254
1255
1256/**
1257 * Checks if there is more code on the line.
1258 */
1259static boolean odin32_more_code_on_line()
1260{
1261 boolean fRc;
1262 int curline = p_line;
1263
1264 _save_pos2(searchsave);
1265 odin32_get_next_code_text2();
1266 fRc = curline == p_line;
1267 _restore_pos2(searchsave);
1268
1269 return fRc;
1270}
1271
1272
1273/**
1274 * Gets the next piece of code.
1275 * Doesn't preserver cursor position.
1276 */
1277static _str odin32_get_next_code_text2()
1278{
1279 _str ch;
1280 do
1281 {
1282 curcol = ++p_col;
1283 end_line()
1284 if (p_col <= curcol)
1285 {
1286 p_line++;
1287 p_col = 1;
1288 }
1289 else
1290 p_col = curcol;
1291
1292 ch = get_text();
1293 //say ch ' ('_asc(ch)')';
1294 while (ch == "#") /* preprocessor stuff */
1295 {
1296 p_col = 1;
1297 p_line++;
1298 ch = get_text();
1299 //say ch ' ('_asc(ch)')';
1300 continue;
1301 }
1302 } while (ch :== ' ' || ch :== "\t" || ch :== "\n" || ch :== "\r" || !odin32_in_code());
1303
1304 return ch;
1305}
1306
Note: See TracBrowser for help on using the repository browser.