]> nuage.metani.fr Git - 3GPP.git/blob - awk/txt2asn-integrated.awk
38331-convert.sh directly converts docx to text and generates ASN.1 with comments...
[3GPP.git] / awk / txt2asn-integrated.awk
1 #!/bin/awk -f
2
3 # Arrays used:
4
5 # Information about each ASN.1 line, indexed by number
6
7 # text: the complete line
8 # field: the field, without suffix (if there is one)
9 # structure: the outer structure (if it is a field)
10 # condition: the condition, if there is one
11
12 # Information about each field description, indexed by outer structure and field name (when a description is for a coma-separated list of fields, a separate entry is created for each field).
13
14 # field_description_len: how many descriptions lines (0 means none)
15 # field_description: the lines of a field descritpion, indexed from 1
16
17 function asn1_print()
18 {
19
20 if (!(1 in text)) { return ; }
21 #print "entering asn1_print";
22 for (line=1; line<=line_number; line++) {
23 #if (field[line] != "") {
24 # print "Ligne " line " champs " field[line] ;
25 # print "Structure " structure[line] ;
26 # print "Description de longueur " field_description_len[structure[line]][field[line]];
27 #}
28 if (((field[line] != "") &&
29 (field_description_len[structure[line]][field[line]] > 0)) ||
30 ((condition[line] != "") &&
31 (condition_description_len[condition[line]] > 0))) {
32
33 indentation = "";
34 position = index(text[line], field[line]) - 1;
35
36 #print "ligne " line " position " position " field " field[line] " structure " structure[line];
37 indentation = "";
38 for (i=0;i<position;i++) {
39 indentation = indentation " ";
40 }
41
42 #print "Il y a " field_description_len[structure[line]][field[line]] " ligne(s)";
43
44 print "";
45
46 if (field_description_len[structure[line]][field[line]] > 0) {
47
48 print indentation "-- " field[line] " : " field_description[structure[line]][field[line]][1];
49
50 for (i=2;i<=field_description_len[structure[line]][field[line]]; i++) {
51
52 print indentation "-- " field_description[structure[line]][field[line]][i];
53
54 }
55 }
56
57 if (condition_description_len[condition[line]] > 0) {
58 if(field[line] != "")
59 {
60 gsub(/(, )*[Nn]eed [MNSR],*/, "", condition_description[condition[line]][1]);
61 print indentation "-- " field[line] " : " condition_description[condition[line]][1];
62
63 for(i=2;i<=condition_description_len[condition[line]];i++) {
64 gsub(/(, )*[Nn]eed [MNSR],*/, "", condition_description[condition[line]][i]);
65 print indentation "--" condition_description[condition[line]][i];
66 }
67 }
68
69
70 if (condition_code[condition[line]] == "")
71 { sub(/-- Cond [A-Za-z0-9_-]+/, "", text[line]); }
72 else
73 { sub(/-- Cond [A-Za-z0-9_-]+/, "-- Need " condition_code[condition[line]], text[line]); }
74 }
75
76 print text[line] ;
77
78
79 }
80
81 else {
82 if (text[line] ~ /-- Cond [A-Za-z0-9_-]+/)
83 {
84 #print "trouvé";
85 if (condition_code[condition[line]] == "")
86 { sub(/-- Cond [A-Za-z0-9_-]+/, "", text[line]); }
87 else
88 {
89 #print "Ligne " text[condition_reference[line]];
90 #print "Condition " ;
91 sub(/-- Cond [A-Za-z0-9_-]+/, "-- Need " condition_code[condition[line]], text[line]); }
92 }
93 #if((line>0) || (text[line] ~ /[a-zA-Z0-9-]/)) {
94 print text[line] ;
95 #}
96 }
97 }
98
99 delete text;
100 delete text_level;
101 delete field;
102 delete structure;
103 delete condition;
104 delete field_description_len;
105 delete field_description;
106 delete condition_description_len;
107 delete condition_description;
108 delete condition_code;
109 delete condition_reference;
110
111 #print "end of asn1_print"
112 }
113
114 function need_code(aaa)
115 {
116 if (aaa ~ /[Nn]eed M[ ,.]/) { return "M" }
117 if (aaa ~ /[Nn]eed N[ ,.]/) { return "N" }
118 if (aaa ~ /[Nn]eed R[ ,.]/) { return "R" }
119 if (aaa ~ /[Nn]eed S[ ,.]/) { return "S" }
120 return ""
121 }
122
123 function level(bbb)
124 {
125 local_bbb1 = bbb
126 local_bbb2 = bbb
127 return gsub(/{/, "", local_bbb1) - gsub(/}/, "", local_bbb2)
128 }
129
130 BEGIN {
131 add_line_after != "" ;
132 separator = "" ;
133
134 wide_separator = "" ;
135 for(i=0;i<=70;i++) {
136 wide_separator = wide_separator "-" ;
137 }
138
139 ie_separator = "-- " ;
140 for (i=0;i<=70;i++) {
141 ie_separator = ie_separator "=" ;
142 }
143
144 }
145
146 /^[0-9]+(\.[0-9]+)*\t/ {
147 if (in_IE == "yes") { asn1_print(); }
148 in_IE = "no" ;
149 }
150
151 /^[A-Za-z0-9-]+ message$/ {
152 # No need to print this
153 next;
154 }
155
156 /^[A-Za-z0-9-]+ information element$/ {
157 # No need to print this
158 next;
159 }
160
161 /^-- ASN1START/ {
162 print "";
163 in_ASN1 = "yes";
164 line_number = 0;
165 #empty_line = "yes";
166 next;
167 }
168
169 /^-- ASN1STOP/ {
170 in_ASN1 = "no";
171 direct_print = "no" ;
172 next;
173 }
174
175 /^-- TAG-/ {
176 next;
177 }
178
179 /^[[:space:]]*$/ {
180
181 if (next_line == "condition") {
182 #print separator ;
183 }
184 if ((next_line == "field description") || (next_line == "field name")){
185 #print separator ;
186 }
187
188 if (next_line != "field description") {
189 next_line = "" ;
190 }
191 # #if (empty_line == "yes") {
192 # next;
193 # }
194
195 current_condition = "" ;
196 if (empty_line == "yes") { next; }
197 empty_line = "yes" ;
198
199
200 #print "empty_line set to yes" ;
201 # print ;
202 }
203
204 /\S/ {
205
206 # The empty_line condition is meant for what is directly printed, i.e. messages decriptions
207 # ASN.1, field descriptions and conditions descriptions are not directly printed, so
208 # this should not apply to them
209
210
211
212 #if ((next_line == "field description") || (next_line == "field name")){
213 empty_line = "no" ;
214 #print "empty_line set to no"
215 #}
216
217 }
218
219 /^-[[:space:]]+ParentIE-WithEM$/ {
220 exit 0 ;
221 }
222
223 /^-[[:space:]]+[A-Za-z0-9-]+$/ {
224 asn1_print();
225
226 # if (empty_line == "yes") {
227 #print "";
228 print ie_separator;
229 print "-- IE: " $2;
230 print "" ;
231 empty_line = "no" ;
232 conditions = "" ;
233 IE_name = $2;
234
235 #if (IE_name == "PosSI-SchedulingInfo") { print "IE trouvé" ; }
236 # }
237 in_IE = "yes" ;
238
239 next ;
240 }
241
242 /^-[[:space:]]+Multiplicity and type constraints? definitions?$/ {
243
244 #print "Trouvé" ;
245 if (in_IE == "yes") {
246 asn1_print();
247 }
248 in_IE = "yes" ;
249 #print "Trouvé 2" ;
250
251 # In this case, directly print ASN.1 without processing
252 direct_print = "yes" ;
253
254 print ie_separator;
255 print "-- IE: Constants";
256 print "" ;
257 empty_line = "no" ;
258 conditions = "" ;
259
260 next ;
261 }
262
263 /^-[[:space:]]+End of [A-Za-z0-9-]+$/ {
264 if (in_IE == "yes") {
265 asn1_print();
266 }
267 in_IE = "yes" ;
268 empty_line = "no" ;
269 conditions = "" ;
270 }
271
272 /^NR-InterNodeDefinitions/ {
273
274 print ie_separator;
275 print "-- IE: NR-InterNodeDefinitions";
276 print "" ;
277 print ;
278
279 empty_line = "no" ;
280 conditions = "" ;
281
282 in_IE = "no" ;
283 direct_print = "yes" ;
284 next ;
285 }
286
287 /^Conditional [Pp]resence/ {
288 add_line_after = "";
289 separator = "" ;
290
291 $0 = "Conditional presence" ;
292 for(i=0;i<=70;i++) {
293 separator = separator "-" ;
294 }
295 # print separator;
296 #add_line_after = separator ;
297 next_line = "condition" ;
298 #print "Conditional Presence"
299 #if (IE_name == "PosSI-SchedulingInfo") { print "condition trouvée" ; }
300 }
301
302 # Need to catch "x and y field descriptions"
303
304 /field descriptions$/ {
305 add_line_after = "";
306 separator = "" ;
307
308 for(i=0;i<=70;i++) {
309 separator = separator "-" ;
310 }
311 # print separator;
312 # add_line_after = separator ;
313 next_line = "field name" ;
314
315 field_struct = $1;
316
317 #print "Trouvé description des champs de " $1;
318 # do not print
319 next;
320 }
321
322 #/^[A-Za-z0-9-]+[[:space:]]+[A-Za-z0-9-]+/ {
323 # if (next_line == "field description") {
324 # add_line_after = separator ;
325 # next_line = "field name";
326 # }
327 #}
328
329 # This is matched for any non-empty line
330 /[A-Za-z0-9-]+/ {
331
332
333 if ((in_IE == "yes") && (in_ASN1 == "no")){
334
335 # if we are coming from a "IE X field description" statement
336 # or we were in a field description
337 if ((next_line == "field name") || (next_line == "field description")) {
338
339
340 # If the whole line is a coma-separated list in an IE (=> field names)
341 if (/^[A-Za-z0-9-]+(, [A-Za-z0-9-]+)*$/) {
342 # Then, this is a new field, or list of fields
343 #print separator ;
344
345 names = $0;
346
347 # remove leading/trailing spaces
348 sub(/^[[:space:]]+/, "", names);
349 sub(/[[:space:]]+$/, "", names);
350
351 # remove comas and duplicate spaces
352 gsub(/,/, "", names);
353 gsub(/[[:space:]]+/, " ", names);
354
355 #print "coucou " names;
356 #print $0;
357
358 delete field_list;
359 # this will delete any previous field_list
360 ret = split(names, field_list, " ");
361
362 #print "hello";
363 #print "split returned " ret ;
364 #for (abc in field_list)
365 #{ print "field_list contient " field_list[abc];}
366
367
368 $0 = "Field: " $0
369 #add_line_after = " ";
370
371 # Add one entry for each of the fields
372 for (ii in field_list) {
373 num = field_description_len[field_struct][field_list[ii]] = 0;
374 #print "Trouvé description de " field_list[ii];
375 }
376
377 if (next_line == "field name") {
378 next_line = "field description";
379 }
380
381 else { next_line = "field name" ; }
382 next;
383 }
384
385 else {
386 # This is a field description
387 #print "coucou";
388 #if (index($0,"BAP")!=0) {
389 #print "BAP trouvé" $0 ;
390 #}
391 #print "contenu " $0;
392
393 if ((next_line == "field name") || (next_line == "field description")) {
394 for (ii in field_list) {
395 field_description_len[field_struct][field_list[ii]]++;
396 num = field_description_len[field_struct][field_list[ii]];
397 field_description[field_struct][field_list[ii]][num] = $0;
398 #print "ajouté une ligne pour " field_list[ii] "dans " field_struct;
399 }
400 next;
401 }
402 }
403 }
404 }
405
406 else if ((in_ASN1 == "yes") && (direct_print == "yes")) {
407 print ;
408 next ;
409 }
410 }
411
412 #/^[A-Za-z0-9-]+/ {
413 # # remove suffix
414 # sub(/-[vr][0-9]+$/, "", $1);
415 #
416 # current_structure = $1 ;
417 #}
418
419
420
421 {
422 if (in_IE == "yes") {
423
424 #print "$0 est " $0 " in_ASN1 est " in_ASN1;
425 if (next_line == "condition") {
426 #print "branche condition " $0;
427 if ($1 != "Conditional") {
428 if (index(conditions, $1) != 0) {
429 current_condition = $1 ;
430 condition_description_len[current_condition] = 1 ;
431 $1 = "" ;
432 condition_description[current_condition][1] = $0 ;
433 condition_code[current_condition] = need_code($0);
434
435 #print separator;
436 #print "-- Condition: " $1;
437
438 #print "Condition " current_condition " trouvée";
439 }
440
441
442 #if ((in_ASN1 == "no") && !(/^\s*$/)) {
443 #$0 = "-- " $0 ;
444 #}
445
446 # prints first line of condition
447 #print $0 " aaa";
448
449
450 else {
451 #print "La description est " $0;
452 condition_description_len[current_condition]++;
453 condition_description[current_condition][condition_description_len[current_condition]] = $0 ;
454 condition_code[current_condition] = need_code($0);
455 }
456 }
457 }
458 else {
459
460 #print "in_ASN1 est " in_ASN1 " ligne " $0;
461 if ((in_ASN1 == "no") && !(/^\s*$/)) {
462 $0 = "-- " $0 ;
463 #print $0 " bbb";
464 }
465
466 if (in_ASN1 == "no") {
467
468 # prints subsequent lines of condition or IE description
469 if ((!(/\S/) && (empty_line == "yes"))) {next}
470 print $0 #" ccc";
471
472 }
473 else {
474 #print line_number;
475 if((line_number==0) && (/^[[:space:]]*$/)) { next ; }
476 line_number++;
477 text[line_number] = $0;
478
479 if (/Multiplicity/) {
480 print "Trouvé 3";
481 print $0;
482 }
483 #print "text[" line_number "] est " text[line_number];
484 if (/^[A-Za-z0-9-]+[[:space:]]+:/) {
485 # remove suffix
486 sub(/-[vr][0-9]+(-IEs)*$/, "", $1);
487 #print "ddd" ;
488 current_structure = $1 ;
489 text_level[line_number] = level(text[line_number]);
490
491 #print $1;
492 }
493 else {
494
495 if (/[[:space:]]+[a-z][A-Za-z0-9-]*/) {
496 text_level[line_number] = text_level[line_number-1] + level(text[line_number]) ;
497
498 # remove suffix
499 sub(/-[vr][0-9]+$/, "", $1);
500 # remove ToAddModList extension suffixes
501 sub(/ToAddModListExt/, "ToAddModList", $1);
502 sub(/ToAddModListSizeExt/, "ToAddModList", $1);
503
504 field[line_number] = $1;
505
506 #print "field est " field[line_number];
507 structure[line_number] = current_structure ;
508 field_description_len[current_structure][$1] = 0;
509
510
511 }
512 else {
513 field[line_number] = "";
514 text_level[line_number] = text_level[line_number-1] + level(text[line_number]) ;
515 }
516
517 if (/-- Cond [A-Za-z0-9_-]+$/) {
518 if(/}\s*(OPTIONAL)*,*\s*-- Cond [A-Za-z0-9_-]+$/) {
519 #print "trouvé" ;
520
521 # The condition should be placed above the field name,
522 # It is something like
523 # field0 ..... level X
524 # field1 { ..... level X+1
525 # abc ABC, ..... level X+1
526 # def DEF ..... level X+1
527 # } OPTIONAL, -- Cond XYZ ..... level X
528 # So we go back up while level > level of the Cond line
529 # Then we reach field0, so this is the line after
530 # We then associate that line with the condition
531
532 for (b=1;text_level[line_number-b]>text_level[line_number];b++) {};
533 condition[line_number-b+1] = $ NF ;
534
535 # Still, to replace -- Cond XXX with - Need M/R/N,
536 # we need to know the line associated with the condition
537 condition_reference[line_number] = line_number-b+1;
538 }
539
540 condition[line_number] = $NF ;
541
542 #print "condition[" line_number "] est " condition[line_number]
543 }
544 else {
545 condition[line_number] = "";
546 }
547 }
548 }
549 }
550 if (add_line_after != "") {
551 print add_line_after ;
552 add_line_after = "" ;
553 }
554
555 if (/-- Cond [A-Za-z0-9_-]+$/) {
556 conditions = conditions " " $NF ;
557 }
558 }
559 else if ((in_ASN1 == "yes") && (direct_print == "yes")) {
560 print ;
561 }
562 }
563