|
@@ -1781,12 +1781,49 @@ implementation
|
|
|
|
|
|
|
|
|
function tinlinenode.handle_copy: tnode;
|
|
|
+
|
|
|
+ procedure do_error(typemismatch:boolean;func:string;fi:tfileposinfo);
|
|
|
+
|
|
|
+ procedure write_dynarray_copy;
|
|
|
+ begin
|
|
|
+ MessagePos1(fileinfo,sym_e_param_list,'Copy(Dynamic Array;'+sizesinttype.typename+'=`<low>`;'+sizesinttype.typename+'=`<length>`);');
|
|
|
+ end;
|
|
|
+
|
|
|
+ begin
|
|
|
+ if typemismatch then
|
|
|
+ CGMessagePos(fi,type_e_mismatch)
|
|
|
+ else
|
|
|
+ CGMessagePos1(fi,parser_e_wrong_parameter_size,'Copy');
|
|
|
+ if func='' then
|
|
|
+ begin
|
|
|
+ write_system_parameter_lists('fpc_shortstr_copy');
|
|
|
+ write_system_parameter_lists('fpc_char_copy');
|
|
|
+ write_system_parameter_lists('fpc_unicodestr_copy');
|
|
|
+ if tf_winlikewidestring in target_info.flags then
|
|
|
+ write_system_parameter_lists('fpc_widestr_copy');
|
|
|
+ write_system_parameter_lists('fpc_ansistr_copy');
|
|
|
+ write_dynarray_copy;
|
|
|
+ end
|
|
|
+ else if func='fpc_dynarray_copy' then
|
|
|
+ write_dynarray_copy
|
|
|
+ else
|
|
|
+ write_system_parameter_lists(func);
|
|
|
+ end;
|
|
|
+
|
|
|
var
|
|
|
paras : tnode;
|
|
|
ppn : tcallparanode;
|
|
|
paradef : tdef;
|
|
|
counter : integer;
|
|
|
+ minargs,
|
|
|
+ maxargs : longint;
|
|
|
+ func : string;
|
|
|
begin
|
|
|
+ if not assigned(left) then
|
|
|
+ begin
|
|
|
+ do_error(false,'',fileinfo);
|
|
|
+ exit(cerrornode.create);
|
|
|
+ end;
|
|
|
result:=nil;
|
|
|
{ determine copy function to use based on the first argument,
|
|
|
also count the number of arguments in this loop }
|
|
@@ -1801,44 +1838,63 @@ implementation
|
|
|
end;
|
|
|
set_varstate(ppn.left,vs_read,[vsf_must_be_valid]);
|
|
|
paradef:=ppn.left.resultdef;
|
|
|
+ { the string variants all require 2 or 3 args, only the array one allows less }
|
|
|
+ minargs:=2;
|
|
|
+ maxargs:=3;
|
|
|
if is_ansistring(paradef) then
|
|
|
- // set resultdef to argument def
|
|
|
- resultdef:=paradef
|
|
|
+ begin
|
|
|
+ // set resultdef to argument def
|
|
|
+ resultdef:=paradef;
|
|
|
+ func:='fpc_ansistr_copy';
|
|
|
+ end
|
|
|
else if (is_chararray(paradef) and (paradef.size>255)) or
|
|
|
((cs_refcountedstrings in current_settings.localswitches) and is_pchar(paradef)) then
|
|
|
- // set resultdef to ansistring type since result will be in ansistring codepage
|
|
|
- resultdef:=getansistringdef
|
|
|
- else
|
|
|
- if is_widestring(paradef) then
|
|
|
- resultdef:=cwidestringtype
|
|
|
- else
|
|
|
- if is_unicodestring(paradef) or
|
|
|
+ begin
|
|
|
+ // set resultdef to ansistring type since result will be in ansistring codepage
|
|
|
+ resultdef:=getansistringdef;
|
|
|
+ func:='fpc_ansistr_copy';
|
|
|
+ end
|
|
|
+ else if is_widestring(paradef) then
|
|
|
+ begin
|
|
|
+ resultdef:=cwidestringtype;
|
|
|
+ func:='fpc_widestr_copy';
|
|
|
+ end
|
|
|
+ else if is_unicodestring(paradef) or
|
|
|
is_widechararray(paradef) or
|
|
|
is_pwidechar(paradef) then
|
|
|
- resultdef:=cunicodestringtype
|
|
|
+ begin
|
|
|
+ resultdef:=cunicodestringtype;
|
|
|
+ func:='fpc_unicodestr_copy';
|
|
|
+ end
|
|
|
else
|
|
|
if is_char(paradef) then
|
|
|
- resultdef:=cshortstringtype
|
|
|
+ begin
|
|
|
+ resultdef:=cshortstringtype;
|
|
|
+ func:='fpc_char_copy';
|
|
|
+ end
|
|
|
else
|
|
|
if is_dynamic_array(paradef) then
|
|
|
begin
|
|
|
- { Only allow 1 or 3 arguments }
|
|
|
- if not(counter in [1..3]) then
|
|
|
- begin
|
|
|
- CGMessage1(parser_e_wrong_parameter_size,'Copy');
|
|
|
- exit;
|
|
|
- end;
|
|
|
+ minargs:=1;
|
|
|
resultdef:=paradef;
|
|
|
+ func:='fpc_dynarray_copy';
|
|
|
+ end
|
|
|
+ else if counter in [2..3] then
|
|
|
+ begin
|
|
|
+ resultdef:=cshortstringtype;
|
|
|
+ func:='fpc_shortstr_copy';
|
|
|
end
|
|
|
else
|
|
|
- begin
|
|
|
- { generic fallback that will give an error if a wrong
|
|
|
- type is passed }
|
|
|
- if (counter=3) or (counter=2) then
|
|
|
- resultdef:=cshortstringtype
|
|
|
- else
|
|
|
- CGMessagePos(ppn.left.fileinfo,type_e_mismatch);
|
|
|
- end;
|
|
|
+ begin
|
|
|
+ do_error(true,'',ppn.left.fileinfo);
|
|
|
+ exit(cerrornode.create);
|
|
|
+ end;
|
|
|
+
|
|
|
+ if (counter<minargs) or (counter>maxargs) then
|
|
|
+ begin
|
|
|
+ do_error(false,func,fileinfo);
|
|
|
+ exit(cerrornode.create);
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
{$maxfpuregisters 0}
|