~ubuntu-branches/ubuntu/natty/ntop/natty

« back to all changes in this revision

Viewing changes to utils/processstruct.awk

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2005-01-30 21:59:13 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20050130215913-xc3ke963bw49b3k4
Tags: 2:3.0-5
* Updated README.Debian file so users will understand what to do at
  install, closes: #291794, #287802.
* Updated ntop init script to give better output.
* Also changed log directory from /var/lib/ntop to /var/log/ntop,
  closes: #252352.
* Quoted the interface list to allow whitespace, closes: #267248.
* Added a couple of logcheck ignores, closes: #269321, #269319.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# ntop xml output generator -- tools
 
2
 
 
3
# Written by and copyright (c) 2002, Burton M. Strauss III
 
4
 
 
5
# Distributed as part of ntop, http://www.ntop.org
 
6
 
 
7
 # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 
8
 #
 
9
 # This program is free software; you can redistribute it and/or modify
 
10
 # it under the terms of the GNU General Public License as published by
 
11
 # the Free Software Foundation; either version 2 of the License, or
 
12
 # (at your option) any later version.
 
13
 #
 
14
 # This program is distributed in the hope that it will be useful,
 
15
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 # GNU General Public License for more details.
 
18
 #
 
19
 # You should have received a copy of the GNU General Public License
 
20
 # along with this program; if not, write to the Free Software Foundation,
 
21
 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
22
 # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 
23
 # 
 
24
 
 
25
# This tool is part of the ntop xml output system, but it is in fact
 
26
# not normally executed by persons compiling ntop.
 
27
 
 
28
# It is designed for the developer of ntop to create a skeleton of 
 
29
# certain files used by xmldump.c
 
30
 
 
31
#  Usage:   awk -f processstruct.awk xxx.h
 
32
 
 
33
# This program processes a c language .h file and attempts to extract
 
34
# the structure definitions (typedef struct) so that it can create
 
35
# (skeleton) subroutines for insertion into xmldump.c
 
36
 
 
37
# It also creates /*XML lines for xmldump.awk to process to create
 
38
# the c language code that populates the DOM mode in xmldump.awk
 
39
 
 
40
# Understand the limitations - this is not a c parser, it's just dumb
 
41
# token matching.  The output is probably pretty good, but it's only
 
42
# a start.  If there are inteligent groupings of the fields, that's
 
43
# not in the struct, well, it won't figure them out.
 
44
 
 
45
# However, if you add a bunch of stuff to a structure, or add a new
 
46
# structure, this should save you from manually creating everything.
 
47
 
 
48
#  Good Luck!
 
49
 
 
50
#     -----Burton
 
51
 
 
52
#
 
53
# Append - stripping trailing blanks and comments.
 
54
#    This is used to build up a single awk string that contains an entire C statement,
 
55
#    even if it crosses line boundaries.
 
56
#
 
57
function specialappend(inputline, append) {
 
58
    outputline = inputline " " append
 
59
    if ( (i=index(outputline, "/*")) > 0) {
 
60
         if ( (j = index(outputline, "*/")) > 0) {
 
61
            if (j < i) {
 
62
                printf("/*XMLNOTE mis-matched comments, may fail */\n")
 
63
            } else {
 
64
                outputline=substr(outputline, 1, i-1) " " substr(outputline, j+2)
 
65
            }
 
66
        }
 
67
    }
 
68
    gsub(/ +$/, "", outputline)
 
69
    return outputline
 
70
}
 
71
 
 
72
BEGIN {
 
73
    programname="processstruct.awk"
 
74
 
 
75
    datestamp = strftime("%Y-%m-%dT%H:%M:%S", systime() )
 
76
 
 
77
    # export debug=anything to turn on debug
 
78
    debug=ENVIRON["XMLDUMPDEBUG"]
 
79
 
 
80
    outputfile=ARGV[1]
 
81
    if ((i=index(outputfile, ".")) > 0) { outputfile = substr(outputfile, 1, i-1) }
 
82
    outputfile=outputfile ".skeleton"
 
83
 
 
84
    if (tolower(substr(ARGV[1], 1, 1)) == "globals-structtypes.h") {
 
85
        xmlprefix="s"
 
86
    } else {
 
87
        xmlprefix=tolower(substr(ARGV[1], 1, 1))
 
88
    }
 
89
 
 
90
    printf("/*XMLNOTE %s %s running */\n", datestamp, programname)
 
91
    printf("/*XMLNOTE     Processing %s -> %s */\n", ARGV[1], outputfile)
 
92
 
 
93
    printf("/*XMLNOTE %s created on %s from %s */\n\n", outputfile, datestamp, ARGV[1]) >outputfile
 
94
 
 
95
    lines=0
 
96
    found_typedef="N"
 
97
    typedef_name=""
 
98
    filename=ARGV[1]
 
99
 
 
100
    xmlprefix=tolower(substr(ARGV[1], 1, 1))
 
101
 
 
102
#
 
103
# This is the translation from c types to /*XML typeflag values
 
104
#   e.g. a float is n:f (numeric, format %f)
 
105
#
 
106
    typewords["float"]="n:f"
 
107
    typewords["int"]="n"
 
108
    typewords["short"]="n"
 
109
    typewords["long"]="n:l"
 
110
    typewords["unsigned"]="n:u"
 
111
    typewords["u_char"]="n:u"
 
112
    typewords["u_int"]="n:u"
 
113
    typewords["u_short"]="n:u"
 
114
    typewords["char"]="s"
 
115
    typewords["volatile"]=""
 
116
    typewords["u_int16_t"]="n:u"
 
117
    typewords["u_int32_t"]="n:u"
 
118
    typewords["u_int"]="n:u"
 
119
    typewords["u_long"]="n:lu"
 
120
 
 
121
#
 
122
# This is used for modifiers (e.g. unsigned int) so that we can merge them.
 
123
#
 
124
    priority_typewords["unsigned"]="u"
 
125
 
 
126
#
 
127
# These are used to list know typeflag values, so we don't output them (optionally, debug)
 
128
# at the end
 
129
#
 
130
    codewords["n"]="y"
 
131
    codewords["s"]="y"
 
132
    codewords["b"]="y"
 
133
    codewords["n:u"]="y"
 
134
    codewords["n:lu"]="y"
 
135
    codewords["n:llu"]="y"
 
136
 
 
137
#
 
138
# These are hard-coded opaque types which we studiously ignore
 
139
#
 
140
    ignore_types["pthread_mutex_t"]="yes"
 
141
    ignore_types["pthread_cond_t"]="yes"
 
142
    ignore_types["gdbm_file"]="yes"
 
143
    ignore_types["file"]="yes"
 
144
    ignore_types["ssl"]="yes"
 
145
    ignore_types["mycode"]="yes"
 
146
 
 
147
#
 
148
# Current .inc output count
 
149
#       Since the name is only valid at the end, we store the generated lines...
 
150
#
 
151
    ocount=0
 
152
 
 
153
    skip="N"
 
154
}
 
155
 
 
156
#
 
157
# Line counter and compress out tabs
 
158
#
 
159
{
 
160
    lines++
 
161
    gsub(/\t/, " ")
 
162
}
 
163
 
 
164
#
 
165
# Skip cpp directives... unless we're in the middle, then just echo...
 
166
#
 
167
substr($1, 1, 1) == "#" { 
 
168
    if ( (found_typedef == "Y") && 
 
169
         ( ($1 == "#if")        || 
 
170
           ($1 == "#ifdef")     || 
 
171
           ($1 == "#ifndef")    || 
 
172
           ($1 == "#elif")      ||
 
173
           ($1 == "#else")      ||
 
174
           ($1 == "#endif") ) ) {
 
175
        outputecho[ocount] = $0
 
176
        ocount++
 
177
    }
 
178
    next 
 
179
}
 
180
 
 
181
# Skip directives
 
182
$1 == "/*XMLSKIPBEGIN" {
 
183
    skip="Y"
 
184
    next
 
185
}
 
186
 
 
187
$1 == "/*XMLSKIPEND" {
 
188
    skip="N"
 
189
    next
 
190
}
 
191
 
 
192
skip == "Y" { next }
 
193
 
 
194
# If all we have is a comment or a blank line, ignore it
 
195
$1 == "/*" && $NF == "*/" { next }
 
196
$0 == ""                  { next }
 
197
/^[ \t]*$/                { next }
 
198
 
 
199
# Comment opening ... skip until the end ... yeah, this is crude...
 
200
$1 == "/*" {
 
201
     while (getline > 0) {
 
202
         lines++
 
203
         if (index($0, "*/") > 0) {
 
204
             next
 
205
         }
 
206
     }
 
207
     next
 
208
}
 
209
 
 
210
#
 
211
# Stuff we care about begins:
 
212
#   typedef struct [optionalcomment] {
 
213
#
 
214
$1 == "typedef" {
 
215
    # Lets skip the simplest ones .... typedef xyz int;
 
216
    if (index($0, ";") > 0) { next }
 
217
    if ($2 != "struct")     { next }
 
218
 
 
219
    found_typedef="Y"
 
220
 
 
221
    printf("  /*XMLNOTE Starting typedef at line %d */\n", lines) 
 
222
    printf("/*XMLNOTE automatically created from %s starting at line %d */\n", 
 
223
           filename, lines) >>outputfile
 
224
 
 
225
    next
 
226
}
 
227
 
 
228
#
 
229
# Ends:
 
230
#   } name;
 
231
#
 
232
$1 == "}" {
 
233
 
 
234
    found_typedef="N"
 
235
 
 
236
    # Create working names... (stripping the ;)
 
237
    #    fname is the name, lfname is lower case and pfname is 1st upper, rest lower
 
238
    fname=$2
 
239
    gsub(/ *;$/, "", fname)
 
240
    lfname = tolower(fname)
 
241
    pfname = toupper(substr(lfname, 1, 1)) substr(lfname, 2)
 
242
    typewords[fname]=lfname
 
243
 
 
244
    # Output the header lines
 
245
    printf("    /*XMLNOTE Creating %s.inc */\n", lfname)
 
246
    printf("/*XMLSECTIONBEGIN xml/%s_%s.inc parent input */\n", xmlprefix, lfname) >>outputfile
 
247
    printf("  /*XML e      %-30s %-20s   \"\" */\n", fname, "parent:Work") >>outputfile
 
248
 
 
249
    # Output the stored lines
 
250
    for (i=0; i<ocount; i++) {
 
251
        if (i in outputecho) {
 
252
            printf("%s\n", outputecho[i]) >>outputfile
 
253
            delete outputecho[i]
 
254
            continue
 
255
        }
 
256
        otype=tolower(outputtype[i])
 
257
        gsub(/\*/, "", otype)
 
258
        if (i in outputindex) {
 
259
            printf("  /*XMLFOR i 0 %s */\n", outputindex[i]) >>outputfile
 
260
            indent="    "
 
261
        } else {
 
262
            indent=""
 
263
        }
 
264
        if (otype != outputfield[i]) {
 
265
            printf("%s  /*XML%s %-6s %-30s %-20s   \"\" */\n", 
 
266
                indent,
 
267
                otype in ignore_types ? "NOTE - IGNORE " : "",
 
268
                otype,
 
269
                outputfield[i] (i in outputindex ? "[i]" : ""),
 
270
                "Work") >>outputfile
 
271
        }
 
272
        if (i in outputindex) {
 
273
            printf("  /*XMLROF */\n") >>outputfile
 
274
            delete outputindex[i]
 
275
        }
 
276
        delete outputfield[i]
 
277
    }
 
278
    printf("/*XMLSECTIONEND */\n\n\n") >>outputfile
 
279
 
 
280
    printf("/* ********************************** */\n") >>outputfile
 
281
    printf("/* *Generated skeleton for xmldump.c* */\n") >>outputfile
 
282
    printf("/* * created from %-17s * */\n", filename) >>outputfile
 
283
    printf("/* *      at line %4d              * */\n", lines) >>outputfile
 
284
    printf("/* *      at %-22s * */\n", datestamp) >>outputfile
 
285
    printf("/* ********************************** */\n\n") >>outputfile
 
286
    printf("GdomeElement * newxml_%s(GdomeElement * parent,\n", lfname) >>outputfile
 
287
    printf("                       char * nodename,\n") >>outputfile
 
288
    printf("                       %s * input,\n", fname) >>outputfile
 
289
    printf("                       char * description);\n\n") >>outputfile
 
290
    printf("GdomeElement * newxml_%s(GdomeElement * parent,\n", lfname) >>outputfile
 
291
    printf("                       char * nodename,\n") >>outputfile
 
292
    printf("                       %s * input,\n", fname) >>outputfile
 
293
    printf("                       char * description) {\n\n") >>outputfile
 
294
    printf("    GdomeElement *elWork;\n") >>outputfile
 
295
    printf("    GdomeException exc;\n\n") >>outputfile
 
296
    printf("#if (XMLDUMP_DEBUG >= 3)\n") >>outputfile
 
297
    printf("        traceEvent(CONST_TRACE_INFO, \"XMLDUMP_DEBUG: Starting newxml_%s\\n\");\n", lfname) >>outputfile
 
298
    printf("#endif\n\n") >>outputfile
 
299
    printf("    /* Insert the generated block of code */\n") >>outputfile
 
300
    printf("        #include \"xml/%s_%s.inc\"\n\n", xmlprefix, lfname) >>outputfile
 
301
    printf("#if (XMLDUMP_DEBUG >= 3)\n") >>outputfile
 
302
    printf("        traceEvent(CONST_TRACE_INFO, \"XMLDUMP_DEBUG: Ending newxml_%s\\n\");\n", lfname) >>outputfile
 
303
    printf("#endif\n\n") >>outputfile
 
304
    printf("    return elWork;\n") >>outputfile
 
305
    printf("}\n\n") >>outputfile
 
306
    printf("/* ********************************** */\n") >>outputfile
 
307
    printf("/* ********************************** */\n\n") >>outputfile
 
308
 
 
309
    # Store the name of the type for later, reset the counter and continue on...
 
310
    typelist[lfname]="y"
 
311
    ocount=0
 
312
    next
 
313
}
 
314
 
 
315
#
 
316
# If we are NOT in the middle of a typedef, then we skip the line...
 
317
#
 
318
found_typedef == "N" { next }
 
319
 
 
320
#
 
321
# Otherwise, it's a definition in our struct and we process it...
 
322
#
 
323
{
 
324
    # Process a line...
 
325
    #    First, read up to the ; dropping comments
 
326
 
 
327
    inputline=""
 
328
    inputline = specialappend(inputline, $0)
 
329
    gsub(/ +$/, "", inputline)
 
330
    while (substr(inputline, length(inputline), 1) != ";") {
 
331
        if (getline > 0) {
 
332
            lines++
 
333
            inputline = specialappend(inputline, $0)
 
334
        } else if (substr($1, 1, 1) == "#") {
 
335
            continue
 
336
        } else {
 
337
            printf("/*XMLNOTE no closing ; - assuming, may fail '%s' */\n", inputline)
 
338
            inputline=inputline ";"
 
339
            break
 
340
        }
 
341
        gsub(/ +$/, "", inputline)
 
342
    }
 
343
    while ( (i=index(inputline, "/*")) > 0) {
 
344
        j = index(inputline, "*/")
 
345
        if (j < i) {
 
346
            printf("/*XMLNOTE mis-matched comments, may fail */\n")
 
347
            break
 
348
        }
 
349
        inputline=substr(inputline, 1, i-1) " " substr(inputline, j+2)
 
350
    }
 
351
    gsub(/ *; *$/, "", inputline)
 
352
    if (debug != "") printf("DEBUG: inputline='%s', NF=%d\n", inputline, NF)
 
353
 
 
354
    # This gives us an entire C declaration statement.  We'll set $0 to it so we can
 
355
    #  use the automatic split and $n variables.
 
356
    $0=inputline
 
357
 
 
358
    # Process the first field(s) to grab the type.
 
359
    #  typetype: We look up the type in the table above until we find the 
 
360
    #            first conversion to /*XML typeflag
 
361
    #  prioritytypetype is the "u" suffix if needed, again from table above.
 
362
    #   This allows us to convert "unsigned int" to n:u while "int" is just "n"
 
363
    #  ActualTypeName is just a concat of the words (unsigned long long -> unsignedlonglong)
 
364
    #      Used below to see if this is a char xx[n] that we should treat as a string.
 
365
    ActualTypeName=""
 
366
    typetype=""
 
367
    prioritytypetype=""
 
368
    for (i=1; i<=NF; i++) {
 
369
      typeword=$i
 
370
      gsub(/\*$/, "", typeword)
 
371
      if (typeword == "struct") { 
 
372
          ActualTypeName=ActualTypeName $i
 
373
          continue
 
374
      } else if (typeword in typewords) {
 
375
          ActualTypeName=ActualTypeName $i
 
376
          if ( (typetype == "") && (typeword in typewords) && (typewords[typeword] != "") ) {
 
377
              typetype = typewords[typeword]
 
378
          }
 
379
          if ( (prioritytypetype == "") && (typeword in prioritytypewords) ) {
 
380
              prioritytypetype = prioritytypewords[typeword]
 
381
          }
 
382
      } else {
 
383
          # Not a type word? Must be the field... stop mucking with types.
 
384
          break
 
385
      }
 
386
    }
 
387
    if (typetype == "" ) { typetype = $i }
 
388
    if (prioritytypetype != "") { 
 
389
        if (index(typetype, ":") == 0) { typetype = typetype ":" }
 
390
        typetype = typetype prioritytypetype
 
391
    }
 
392
    if (debug != "") printf("DEBUG: typetype='%s'\n", typetype)
 
393
 
 
394
    # Process the remaining field(s) as variables of the associated type...
 
395
    if (debug != "") printf("DEBUG: i=%d, NF=%d\n", i, NF)
 
396
    for (; i<=NF; i++) {
 
397
        if (debug != "") printf("DEBUG: processing field '%s'\n", $i)
 
398
        # Convert **x to x[] 
 
399
        if (substr($i, 1, 2) == "**") { 
 
400
            $i = substr($i, 3) "[?]" 
 
401
            ActualTypeName="forcedarray"
 
402
        }
 
403
        # If it's got an index value, we need to know for the XMLFOR later on...
 
404
        j=index($i, "[")
 
405
        if (j>0) {
 
406
            field=substr($i, 1, j-1)
 
407
            findex=substr($i, j+1)
 
408
            gsub(/\]/, "", findex)
 
409
        } else {
 
410
            field=$i
 
411
            findex=""
 
412
        }
 
413
        # Strip off bit masks, leading *'s, trailing commas
 
414
        gsub(/^:[0-9]*/, "", field)
 
415
        gsub(/^\*+/, "", field)
 
416
        gsub(/\*+$/, "", field)
 
417
        gsub(/,$/, "", field)
 
418
        if (debug != "") printf("DEBUG: Field %s, type %s\n", field, typetype)
 
419
 
 
420
        if (tolower(field) in ignore_types) {
 
421
        } else if (field != "") {
 
422
            # Store the output data for when we find the }
 
423
            outputtype[ocount] = typetype
 
424
            outputfield[ocount]= field
 
425
            if (findex != "") { 
 
426
                if (ActualTypeName ~ /char/) {
 
427
                    # char xxx[size]  -- treat as string
 
428
                } else {
 
429
                    outputindex[ocount] = findex 
 
430
                }
 
431
            }
 
432
            ocount++
 
433
        }
 
434
    }
 
435
    next
 
436
}
 
437
 
 
438
END {
 
439
    datestamp = strftime("%Y-%m-%dT%H:%M:%S", systime() )
 
440
##    # Note we explicitly APPEND to the list, in case we have multiple files to process...
 
441
##    print "# processstruct.list created " datestamp >>"processstruct.list"
 
442
##    print "#    by processstruct.awk "              >>"processstruct.list"
 
443
##    print "#    from " ARGV[1]                      >>"processstruct.list"
 
444
##    print "#"                                       >>"processstruct.list"
 
445
 
 
446
    # Output a list of all the unknown types we've found for xmldump.awk
 
447
##    for (i in typelist) {
 
448
##        if (i in typewords) {
 
449
##            printf("# typewords   %s\n", i) >>"processstruct.list"
 
450
##        } else if (i in codewords) {
 
451
##            printf("# codewords   %s\n", i) >>"processstruct.list"
 
452
##        } else {
 
453
##            printf("struct        %s\n", i) >>"processstruct.list"
 
454
##        }
 
455
##    }
 
456
    printf("\n\n/*XMLNOTE %s %s finished */\n\n\n", datestamp, programname)
 
457
}