@@ -812,94 +812,62 @@ create or replace package body ut_utils is
812812 return l_result;
813813 end replace_multiline_comments;
814814
815- function replace_multiline_comments(a_source clob) return clob is
816- l_result clob;
817- l_ml_comment_start binary_integer := 1;
818- l_comment_start binary_integer := 1;
819- l_text_start binary_integer := 1;
820- l_escaped_text_start binary_integer := 1;
821- l_escaped_text_end_char varchar2(1 char);
822- l_end binary_integer := 1;
823- l_ml_comment clob;
824- l_newlines_count binary_integer;
825- l_offset binary_integer := 1;
826- l_length binary_integer := coalesce(dbms_lob.getlength(a_source), 0);
827- begin
828- l_ml_comment_start := instr(a_source,'/*');
829- l_comment_start := instr(a_source,'--');
830- l_text_start := instr(a_source,'''');
831- l_escaped_text_start := instr(a_source,q'[q']');
832- while l_offset > 0 and l_ml_comment_start > 0 loop
833-
834- if l_ml_comment_start > 0 and (l_ml_comment_start < l_comment_start or l_comment_start = 0)
835- and (l_ml_comment_start < l_text_start or l_text_start = 0)and (l_ml_comment_start < l_escaped_text_start or l_escaped_text_start = 0)
836- then
837- l_end := instr(a_source,'*/',l_ml_comment_start+2);
838- append_to_clob(l_result, dbms_lob.substr(a_source, l_ml_comment_start-l_offset, l_offset));
839- if l_end > 0 then
840- l_ml_comment := substr(a_source, l_ml_comment_start, l_end-l_ml_comment_start);
841- l_newlines_count := length( l_ml_comment ) - length( translate( l_ml_comment, 'a'||chr(10), 'a') );
842- if l_newlines_count > 0 then
843- append_to_clob(l_result, lpad( chr(10), l_newlines_count, chr(10) ) );
844- end if;
845- l_end := l_end + 2;
846- end if;
847- else
815+ function strip_create_header_lines(a_source dbms_preprocessor.source_lines_t)
816+ return dbms_preprocessor.source_lines_t
817+ is
818+ l_result dbms_preprocessor.source_lines_t := a_source;
819+ l_rebased dbms_preprocessor.source_lines_t;
820+ l_create_line pls_integer;
821+ l_header_line pls_integer;
822+ l_header_pos pls_integer := 0;
823+ begin
824+ if l_result.count = 0 then
825+ return l_result;
826+ end if;
848827
849- if l_comment_start > 0 and (l_comment_start < l_ml_comment_start or l_ml_comment_start = 0)
850- and (l_comment_start < l_text_start or l_text_start = 0) and (l_comment_start < l_escaped_text_start or l_escaped_text_start = 0)
851- then
852- l_end := instr(a_source,chr(10),l_comment_start+2);
853- if l_end > 0 then
854- l_end := l_end + 1;
855- end if;
856- elsif l_text_start > 0 and (l_text_start < l_ml_comment_start or l_ml_comment_start = 0)
857- and (l_text_start < l_comment_start or l_comment_start = 0) and (l_text_start < l_escaped_text_start or l_escaped_text_start = 0)
858- then
859- l_end := instr(a_source,q'[']',l_text_start+1);
860-
861- --skip double quotes while searching for end of quoted text
862- while l_end > 0 and l_end = instr(a_source,q'['']',l_text_start+1) loop
863- l_end := instr(a_source,q'[']',l_end+1);
864- end loop;
865- if l_end > 0 then
866- l_end := l_end + 1;
867- end if;
828+ -- remove comment lines that contain "-- create or replace" and find first CREATE
829+ for i in 1..l_result.count loop
830+ l_result(i) := regexp_replace(l_result(i), '^.*[-]{2,}\s*create(\s+or\s+replace).*$', null, 1, 1, 'i');
831+ if l_create_line is null and regexp_like(l_result(i), '(^|[[:space:]])create([[:space:]]|$)', 'i') then
832+ l_create_line := i;
833+ end if;
834+ end loop;
868835
869- elsif l_escaped_text_start > 0 and (l_escaped_text_start < l_ml_comment_start or l_ml_comment_start = 0)
870- and (l_escaped_text_start < l_comment_start or l_comment_start = 0) and (l_escaped_text_start < l_text_start or l_text_start = 0)
871- then
872- --translate char "[" from the start of quoted text "q'[someting]'" into "]"
873- l_escaped_text_end_char := translate(substr(a_source, l_escaped_text_start + 2, 1),gc_open_chars,gc_close_chars);
874- l_end := instr(a_source,l_escaped_text_end_char||'''',l_escaped_text_start + 3 );
875- if l_end > 0 then
876- l_end := l_end + 2;
877- end if;
836+ -- find first occurrence of object keyword after CREATE (may be on later line)
837+ if l_create_line is not null then
838+ for i in l_create_line..l_result.count loop
839+ l_header_pos := regexp_instr(
840+ l_result(i),
841+ '(^|[[:space:]])(package|type|procedure|function)([[:space:]]|$)',
842+ 1, 1, 0, 'i', 2
843+ );
844+ if l_header_pos > 0 then
845+ l_header_line := i;
846+ exit;
878847 end if;
848+ end loop;
879849
880- if l_end = 0 then
881- append_to_clob(l_result, substr(a_source, l_offset, l_length-l_offset));
882- else
883- append_to_clob(l_result, substr(a_source, l_offset, l_end-l_offset));
884- end if;
885- end if;
886- l_offset := l_end;
887- if l_offset >= l_ml_comment_start then
888- l_ml_comment_start := instr(a_source,'/*',l_offset);
889- end if;
890- if l_offset >= l_comment_start then
891- l_comment_start := instr(a_source,'--',l_offset);
892- end if;
893- if l_offset >= l_text_start then
894- l_text_start := instr(a_source,'''',l_offset);
895- end if;
896- if l_offset >= l_escaped_text_start then
897- l_escaped_text_start := instr(a_source,q'[q']',l_offset);
850+ if l_header_line is not null then
851+ -- keep from keyword onward on the header line
852+ l_result(l_header_line) := substr(l_result(l_header_line), l_header_pos);
853+ -- remove "OWNER." from create or replace statement.
854+ -- Owner is not supported along with AUTHID - see issue https://github.com/utPLSQL/utPLSQL/issues/1088
855+ l_result(l_header_line) := regexp_replace(
856+ l_result(l_header_line),
857+ '^(package|type|procedure|function)\s+("?[[:alpha:]][[:alnum:]$#_]*"?\.)(.*)',
858+ '\1 \3', 1, 1, 'ni'
859+ );
860+
861+ -- rebase so header line becomes line 1 (matches preprocessor expectations)
862+ for i in l_header_line .. l_result.count loop
863+ l_rebased(i - l_header_line + 1) := l_result(i);
864+ end loop;
865+ return l_rebased;
898866 end if;
899- end loop ;
900- append_to_clob(l_result, substr(a_source, l_end));
867+ end if ;
868+
901869 return l_result;
902- end;
870+ end strip_create_header_lines ;
903871
904872 function get_child_reporters(a_for_reporters ut_reporters_info := null) return ut_reporters_info is
905873 l_for_reporters ut_reporters_info := a_for_reporters;
0 commit comments