4
%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
6
%% The contents of this file are subject to the Erlang Public License,
7
%% Version 1.1, (the "License"); you may not use this file except in
8
%% compliance with the License. You should have received a copy of the
9
%% Erlang Public License along with this software. If not, it can be
10
%% retrieved online at http://www.erlang.org/.
12
%% Software distributed under the License is distributed on an "AS IS"
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
%% the License for the specific language governing rights and limitations
20
%%----------------------------------------------------------------------
21
%% Purpose : Test suite for the IDL preprocessor
22
%%----------------------------------------------------------------------
25
-include_lib("test_server/include/test_server.hrl").
29
%% Standard options to the ic compiler, NOTE unholy use of OutDir
31
-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])).
33
-define(GCC_VER, "2.95.3").
35
-export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2]).
36
-export([arg_norm/1]).
37
-export([cascade_norm/1]).
38
-export([comment_norm/1]).
39
-export([concat_norm/1]).
40
-export([define_norm/1]).
43
-export([misc_norm/1]).
44
-export([improp_nest_constr_norm/1]).
45
-export([inc_norm/1]).
46
-export([line_norm/1]).
47
-export([nopara_norm/1]).
48
-export([predef_norm/1]).
49
-export([predef_time_norm/1]).
50
-export([self_ref_norm/1]).
51
-export([separate_norm/1]).
52
-export([swallow_sc_norm/1]).
53
-export([unintended_grp_norm/1]).
54
-export([cases/0, init_per_suite/1, end_per_suite/1]).
57
suite() -> [{ct_hooks,[ts_install_cth]}].
63
[{arg, [], [arg_norm]}, {cascade, [], [cascade_norm]},
64
{comment, [], [comment_norm]},
65
{concat, [], [concat_norm]},
66
{define, [], [define_norm]}, {inc, [], [inc_norm]},
67
{improp_nest_constr, [], [improp_nest_constr_norm]},
68
{misc, [], [misc_norm]}, {line, [], [line_norm]},
69
{nopara, [], [nopara_norm]},
70
{predef, [], [predef_norm]},
71
{predef_time, [], [predef_time_norm]},
72
{self_ref, [], [self_ref_norm]},
73
{separate, [], [separate_norm]},
74
{swallow_sc, [], [swallow_sc_norm]},
75
{unintended_grp, [], [unintended_grp_norm]},
76
{'if', [],[if_norm, if_zero]}].
78
init_per_group(_GroupName, Config) ->
81
end_per_group(_GroupName, Config) ->
85
init_per_suite(Config) ->
90
{skipped, "Very unplesent to run on windows"};
95
exit("Config not a list")
99
case os:find_executable(?GCC) of
102
lists:flatten(io_lib:format("Can not run without ~s in path",
105
case trim(os:cmd(?GCC++" --version")) of
108
?GCC_VER++[D|_] when is_integer(D), D>=$0, D=<$9 ->
109
fail_gcc(?GCC_VER++[D]);
118
{skipped, lists:flatten(io_lib:format("Need ~s v~s, not ~s",
119
[?GCC, ?GCC_VER, Ver]))}.
121
trim(S) -> lists:reverse(skip_white(lists:reverse(skip_white(S)))).
123
skip_white([$\s|T]) -> skip_white(T);
124
skip_white([$\n|T]) -> skip_white(T);
125
skip_white([$\r|T]) -> skip_white(T);
126
skip_white([$\t|T]) -> skip_white(T);
130
end_per_suite(Config) ->
135
[{group, arg}, {group, cascade}, {group, comment},
136
{group, concat}, {group, define}, {group, misc}, {group, 'if'},
137
{group, improp_nest_constr}, {group, inc},
138
{group, line}, {group, nopara}, {group, predef},
139
{group, predef_time}, {group, self_ref},
140
{group, separate}, {group, swallow_sc},
141
{group, unintended_grp}].
145
%%--------------------------------------------------------------------
147
%%--------------------------------------------------------------------
150
arg_norm(doc) -> ["Checks arguments for #define."];
151
arg_norm(suite) -> [];
152
arg_norm(Config) when is_list(Config) ->
153
DataDir = ?config(data_dir, Config),
154
_OutDir = ?OUT(arg_norm),
155
File = filename:join(DataDir, arg),
157
?line ok = test_file(File, DataDir),
161
%%--------------------------------------------------------------------
163
%%--------------------------------------------------------------------
166
cascade_norm(doc) -> ["Check cascade #define."];
167
cascade_norm(suite) -> [];
168
cascade_norm(Config) when is_list(Config) ->
169
DataDir = ?config(data_dir, Config),
170
_OutDir = ?OUT(cascade_norm),
171
File = filename:join(DataDir, cascade),
173
?line ok = test_file(File, DataDir),
177
%%--------------------------------------------------------------------
179
%%--------------------------------------------------------------------
182
comment_norm(doc) -> ["Check comments."];
183
comment_norm(suite) -> [];
184
comment_norm(Config) when is_list(Config) ->
185
DataDir = ?config(data_dir, Config),
186
_OutDir = ?OUT(comment_norm),
187
File = filename:join(DataDir, comment),
189
?line ok = test_file(File, DataDir),
193
%%--------------------------------------------------------------------
195
%%--------------------------------------------------------------------
198
concat_norm(doc) -> ["Check concatinations, i.e ## ."];
199
concat_norm(suite) -> [];
200
concat_norm(Config) when is_list(Config) ->
201
DataDir = ?config(data_dir, Config),
202
_OutDir = ?OUT(concat_norm),
203
File = filename:join(DataDir, concat),
205
?line ok = test_file(File, DataDir),
209
%%--------------------------------------------------------------------
211
%%--------------------------------------------------------------------
214
define_norm(doc) -> ["Check misceleaneous #define."];
215
define_norm(suite) -> [];
216
define_norm(Config) when is_list(Config) ->
217
DataDir = ?config(data_dir, Config),
218
_OutDir = ?OUT(define_norm),
219
File = filename:join(DataDir, define),
221
?line ok = test_file(File, DataDir),
225
%%--------------------------------------------------------------------
227
%%--------------------------------------------------------------------
229
if_norm(doc) -> ["Check #if, #elif, and #endif. ."];
230
if_norm(suite) -> [];
231
if_norm(Config) when is_list(Config) ->
232
DataDir = ?config(data_dir, Config),
233
_OutDir = ?OUT(if_norm),
234
File = filename:join(DataDir, 'if'),
236
?line ok = test_file(File, DataDir),
239
if_zero(doc) -> ["Check #if 0"];
240
if_zero(suite) -> [];
241
if_zero(Config) when is_list(Config) ->
242
DataDir = ?config(data_dir, Config),
243
_OutDir = ?OUT(if_zero),
244
File = filename:join(DataDir, if_zero),
246
?line ok = test_file(File, DataDir),
250
%%--------------------------------------------------------------------
252
%%--------------------------------------------------------------------
255
inc_norm(doc) -> ["Check #include."];
256
inc_norm(suite) -> [];
257
inc_norm(Config) when is_list(Config) ->
258
DataDir = ?config(data_dir, Config),
259
_OutDir = ?OUT(inc_norm),
260
File = filename:join(DataDir, inc),
262
?line ok = test_file(File, DataDir),
267
%%--------------------------------------------------------------------
268
%% improp_nest_constr
269
%%--------------------------------------------------------------------
272
improp_nest_constr_norm(doc) -> ["Check improperly nested constructs."];
273
improp_nest_constr_norm(suite) -> [];
274
improp_nest_constr_norm(Config) when is_list(Config) ->
275
DataDir = ?config(data_dir, Config),
276
_OutDir = ?OUT(improp_nest_constr_norm),
277
File = filename:join(DataDir, improp_nest_constr),
279
?line ok = test_file(File, DataDir),
283
%%--------------------------------------------------------------------
285
%%--------------------------------------------------------------------
288
misc_norm(doc) -> ["Misceleaneous checks."];
289
misc_norm(suite) -> [];
290
misc_norm(Config) when is_list(Config) ->
291
DataDir = ?config(data_dir, Config),
292
_OutDir = ?OUT(misc_norm),
293
File = filename:join(DataDir, misc),
295
?line ok = test_file(File, DataDir),
299
%%--------------------------------------------------------------------
301
%%--------------------------------------------------------------------
304
line_norm(doc) -> ["Checks #line."];
305
line_norm(suite) -> [];
306
line_norm(Config) when is_list(Config) ->
307
DataDir = ?config(data_dir, Config),
308
_OutDir = ?OUT(line_norm),
309
File = filename:join(DataDir, line),
311
?line ok = test_file(File, DataDir),
315
%%--------------------------------------------------------------------
317
%%--------------------------------------------------------------------
320
nopara_norm(doc) -> ["Checks #define with no parameters."];
321
nopara_norm(suite) -> [];
322
nopara_norm(Config) when is_list(Config) ->
323
DataDir = ?config(data_dir, Config),
324
_OutDir = ?OUT(nopara_norm),
325
File = filename:join(DataDir, nopara),
327
?line ok = test_file(File, DataDir),
331
%%--------------------------------------------------------------------
333
%%--------------------------------------------------------------------
336
predef_norm(doc) -> ["Checks predefined macros. Note: not __TIME__ and __DATE__."];
337
predef_norm(suite) -> [];
338
predef_norm(Config) when is_list(Config) ->
339
DataDir = ?config(data_dir, Config),
340
_OutDir = ?OUT(predef_norm),
341
File = filename:join(DataDir, predef),
343
?line ok = test_file(File, DataDir),
347
%%--------------------------------------------------------------------
349
%%--------------------------------------------------------------------
352
predef_time_norm(doc) -> ["Checks the predefined macros __TIME__ and __DATE__."];
353
predef_time_norm(suite) -> [];
354
predef_time_norm(Config) when is_list(Config) ->
355
DataDir = ?config(data_dir, Config),
356
_OutDir = ?OUT(predef_time_norm),
357
File = filename:join(DataDir, predef_time),
359
?line ok = test_file(File, DataDir),
363
%%--------------------------------------------------------------------
365
%%--------------------------------------------------------------------
368
self_ref_norm(doc) -> ["Checks self referring macros."];
369
self_ref_norm(suite) -> [];
370
self_ref_norm(Config) when is_list(Config) ->
371
DataDir = ?config(data_dir, Config),
372
_OutDir = ?OUT(self_ref_norm),
373
File = filename:join(DataDir, self_ref),
375
?line ok = test_file(File, DataDir),
379
%%--------------------------------------------------------------------
381
%%--------------------------------------------------------------------
384
separate_norm(doc) -> ["Checks separete expansion of macro arguments."];
385
separate_norm(suite) -> [];
386
separate_norm(Config) when is_list(Config) ->
387
DataDir = ?config(data_dir, Config),
388
_OutDir = ?OUT(separate_norm),
389
File = filename:join(DataDir, separate),
391
?line ok = test_file(File, DataDir),
395
%%--------------------------------------------------------------------
397
%%--------------------------------------------------------------------
400
swallow_sc_norm(doc) -> ["Checks swallowing an undesirable semicolon."];
401
swallow_sc_norm(suite) -> [];
402
swallow_sc_norm(Config) when is_list(Config) ->
403
DataDir = ?config(data_dir, Config),
404
_OutDir = ?OUT(swallow_sc_norm),
405
File = filename:join(DataDir, swallow_sc),
407
?line ok = test_file(File, DataDir),
411
%%--------------------------------------------------------------------
413
%%--------------------------------------------------------------------
416
unintended_grp_norm(doc) -> ["Checks unintended grouping of arithmetic."];
417
unintended_grp_norm(suite) -> [];
418
unintended_grp_norm(Config) when is_list(Config) ->
419
DataDir = ?config(data_dir, Config),
420
_OutDir = ?OUT(unintended_grp_norm),
421
File = filename:join(DataDir, unintended_grp),
423
?line ok = test_file(File, DataDir),
430
test_file(FileT, DataDir) ->
431
case test_file_1(FileT, DataDir) of
435
{error,{FileT,DataDir}}
438
test_file_1(FileT, DataDir) ->
439
Tok = string:tokens(FileT, "/"),
440
FileName = lists:last(Tok),
441
File = FileT++".idl",
443
?line test_server:format("File ~p~n",[File]),
444
?line test_server:format("FileName ~p~n",[FileName]),
446
Flags = "-I"++DataDir,
448
?line test_server:format("Flags ~p~n",[Flags]),
450
?line Erl = pp_erl(File, Flags),
451
?line Gcc = pp_gcc(File, Flags),
455
?line test_server:format("Internal_pp Result ~n==================~n~p~n~n",[Erl]);
456
{warning, _ErlWar} ->
457
?line test_server:format("Internal_pp Result ~n==================~n~p~n~n",[Erl]);
459
?line test_server:format("Internal_pp Result ~n==================~n~s~n~n",[Erl])
464
Error = string:tokens(GccError, "\n"),
465
?line test_server:format(?GCC" Result ~n==========~n~p~n~n",
468
?line test_server:format(?GCC" Result ~n==========~n~s~n~n",[Gcc])
473
?line case {Erl,Gcc} of
474
{{warning,W}, {error,X}} ->
475
?line case is_ok(W,X) of
479
io_lib:format("Internal_pp found Warning = ~p ~n"
480
?GCC" found Error = ~p~n",[W,X])
485
io_lib:format(?GCC" did not find warnings while ~n"
486
"Internal_pp found the following Warning = ~p~n",[W]);
488
{{error,E}, {error,X}} ->
489
?line case is_ok(E,X) of
493
io_lib:format("Internal_pp found Error = ~p ~n"
494
?GCC" found Error = ~p~n",[E,X])
498
?line case FileName of
500
?line case if_res(E) of
504
io_lib:format(?GCC" did not find errors while ~n"
505
"Internal_pp found the following Error = ~p~n",[E])
508
io_lib:format(?GCC" did not find errors while ~n"
509
"Internal_pp found the following Error = ~p~n",[lists:flatten(E)])
513
io_lib:format("Internal_pp did not find errors while ~n"
514
?GCC" found the following Error = ~p~n",[X]);
518
?line file:write_file("/tmp/Erl.pp",list_to_binary(Erl)),
519
?line file:write_file("/tmp/Gcc.pp",list_to_binary(Gcc)),
521
?line Res = os:cmd("diff -b -w /tmp/Erl.pp /tmp/Gcc.pp"),
522
?line test_server:format("///////////{error,E} E ~p FileName~p~n",[Res,FileName]),
523
?line case {Res, FileName} of
525
?line test_server:format("Diff = [] OK!!!!!!~n"),
527
{_, "predef_time"} ->
528
Tokens = string:tokens(Res,"\n"),
529
?line test_server:format("///////////{error,E} Tokens~p~n",[Tokens]),
531
["3c3",_,"---",_,"5c5",_,"---",_,"9c9",_,"---",_] ->
534
io_lib:format("Diff Result = ~p~n",[Res])
537
io_lib:format("Diff Result = ~p~n",[Res])
545
pp_erl(File, Flags) ->
546
case ic_pp:run(File,Flags) of
547
{ok, [$#, $ , $1 | Rest], []} ->
549
{ok, [$#, $ , $1 | _Rest], Warning} ->
555
pp_gcc(File, Flags) ->
556
Cmd = ?GCC" -x c++ -E",
557
Line = Cmd++" "++Flags++" "++File,
560
[$#, $ , $1 | Rest] ->
564
case string:str(Res,"# 1 \"") of
568
{error, string:sub_string(Res, 1, X-1)}
575
is_ok([{FileName,Line,Text}|T],Gcc) ->
576
Str = FileName++":"++integer_to_list(Line)++": "++Text,
577
case string:str(Gcc,Str) of
579
io:format("~n is_ok Internal_pp missed Error = ~s~n",[Str]),
584
is_ok([Str|T],Gcc) ->
585
case string:str(Gcc,Str) of
587
io:format("~n is_ok Internal_pp missed Error = ~s~n",[Str]),
594
to_list(X) when is_atom(X) -> atom_to_list(X);
603
%% Dir = "/clearcase/otp/libraries/ic/test/ic_pp_SUITE_data/if.idl",
605
{1, {_Dir, 2, "only '#if 0' is implemented at present"}} ->
607
{2, {_Dir, 3, "only '#if 0' is implemented at present"}} ->
609
{3, {_Dir, 5, "`else' command is not implemented at present"}} ->
611
{4, {_Dir, 9, "`elif' command is not implemented at present"}} ->
613
{5, {_Dir, 11, "`else' command is not implemented at present"}} ->