uml (3934B)
1 #!/usr/bin/awk -f 2 3 function is_class( identifier ) { 4 return identifier == "struct" || identifier == "class"; 5 } 6 7 function print_ft_name() { 8 printf( "\"" ); 9 for( i = 2; i < NF; ++i ) 10 { 11 printf( "%s ", $i ); 12 } 13 printf( "%s\"", $NF ); 14 } 15 16 function end_class() { 17 if( class != "" ) 18 { 19 printf( "}\"\n]\n" ); 20 prev_class = class; 21 class = ""; 22 } 23 class_type = ""; 24 inside = ""; 25 fields_max = 0 26 fields_cur = 0 27 } 28 29 function fun( overload ) { 30 if( inside != "fun" ) 31 { 32 printf( "|" ); 33 inside = "fun"; 34 } 35 printf( "%s %s(", scope, $3 ) 36 for( i = 4; i <= NF; ++i ) 37 { 38 gsub( ":", " ", $i ); 39 printf( "%s%s", i == 4 ? "" : ", ", $i ); 40 } 41 printf( "): %s %s\l", $2, overload ); 42 } 43 44 function relation( to, tail, head, label, multiplicity ) { 45 printf( "%s -> %s [ dir = \"both\", arrowtail = \"%s\", arrowhead = \"%s\"", prev_class, to, tail, head ); 46 if( label != "" ) 47 { 48 printf( ", label = \"%s\"", label ); 49 } 50 if( multiplicity != "" ) 51 { 52 if( multiplicity ~ /[0-9]*:[0-9n]*/ ) 53 { 54 split( multiplicity, labels, ":" ); 55 printf( ", taillabel = \"%s\", headlabel = \"%s\"", labels[1], labels[2] ); 56 } 57 else 58 { 59 printf( ", headlabel = \"%s\"", multiplicity ); 60 } 61 } 62 } 63 64 function close_relation() { 65 printf( " ];\n" ); 66 } 67 68 function depends( type ) { 69 end_class(); 70 relation( $2, "none", "vee", type ); 71 printf( " style = \"dotted\"" ); 72 close_relation(); 73 } 74 75 BEGIN { 76 printf( "digraph %s\n{\n", FILENAME ); 77 class = ""; 78 prev_class = ""; 79 class_type = ""; 80 inside = ""; 81 } 82 83 $0 ~ "^[ \t]*private" { scope = "[-]"; } 84 $0 ~ "^[ \t]*protected" { scope = "[#]"; } 85 $0 ~ "^[ \t]*public" { scope = "[+]"; } 86 $0 == "package" { scope = "[~]"; } 87 88 $1 == "splines" { 89 end_class(); 90 printf( "splines = %s;\n", $2 ); 91 } 92 93 $1 == "package_font" { 94 end_class(); 95 printf( "fontname = " ); 96 print_ft_name(); 97 printf( ";\n" ); 98 } 99 100 $1 == "class_font" { 101 end_class(); 102 printf( "node [fontname = " ); 103 print_ft_name(); 104 printf( "];\n" ); 105 } 106 107 $1 == "link_font" { 108 end_class(); 109 printf( "edge [fontname = " ); 110 print_ft_name(); 111 printf( "];\n" ); 112 } 113 114 $1 == "enum" || $1 == "bitfield" || is_class( $1 ) { 115 end_class(); 116 117 if( NF == 3 ) 118 { 119 fields_max = $3 120 fields_cur = 0 121 } 122 scope = "[ ]"; 123 printf( "\n\n" ); 124 class = $2; 125 class_type = $1; 126 special = ""; # for templates, enums, bitfields, structs (why not)... 127 if ( class_type != "class" ) 128 { 129 scope = ""; 130 special = "«" class_type; 131 if ( fields_max != 0 ) 132 { 133 special = special "(" fields_max ")"; 134 } 135 special = special "» "; 136 } 137 printf( "%s\n[\n\tshape=\"record\";\n\tlabel=\"{%s%s", class, special, class ); 138 } 139 140 $1 == "fun" { 141 fun( "" ); 142 } 143 144 $1 == "virtual" { 145 fun( "[[VIRT]]" ); 146 } 147 148 $1 == "abstract" { 149 fun( "[[ABST]]" ); 150 } 151 152 $1 == "var" { 153 if( inside != "var" ) 154 { 155 printf( "|" ); 156 inside = "var"; 157 } 158 printf( "%s%s: %s", scope, $3, $2 ); 159 if( NF == 4 ) 160 { 161 printf( " = %s", $4 ); 162 } 163 printf( "\l" ); 164 } 165 166 $1 == "val" { 167 if( inside != "val" ) 168 { 169 printf( "|" ); 170 inside = "val"; 171 } 172 error = ""; 173 if ( fields_max != 0 ) 174 { 175 ++fields_cur; 176 if ( fields_cur > fields_max ) 177 { 178 error = "EE: " 179 } 180 } 181 if ( is_class( class_type ) ) 182 { 183 printf( "%s%s %s", error, scope, $2 ); 184 } 185 else 186 { 187 if ( fields_max != 0 ) 188 { 189 printf( "%s%d: %s", error, fields_cur, $2 ); 190 } 191 else 192 { 193 printf( "%s%s", error, $2 ); 194 } 195 } 196 printf( "\l" ); 197 } 198 199 $1 == "inherit" { 200 end_class(); 201 relation( $2, "none", "empty" ); 202 close_relation(); 203 } 204 205 $1 == "associate" { 206 end_class(); 207 relation( $2, "none", "vee", $3, $4 ); 208 close_relation(); 209 } 210 211 $1 == "aggreg" { 212 end_class(); 213 relation( $2, "odiamond", "vee", $3, $4 ); 214 close_relation(); 215 } 216 217 $1 == "compose" { 218 end_class(); 219 relation( $2, "diamond", "vee", $3, $4 ); 220 close_relation(); 221 } 222 223 $1 == "depends" { 224 depends( "" ); 225 } 226 227 $1 == "friend" { 228 depends( "friend" ); 229 } 230 231 $1 == "package" { 232 end_class(); 233 printf( "\nsubgraph cluster%s\n{\nlabel = \"%s\" ", $2, $2 ); 234 } 235 236 $1 == "endpackage" { 237 end_class(); 238 printf( "}\n" ); 239 } 240 241 END { 242 end_class(); 243 printf( "}\n" ); 244 }