Document the new Copy Profile button.
[obnox/wireshark/wip.git] / epan / column.c
1 /* column.c
2  * Routines for handling column preferences
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <errno.h>
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #include <epan/timestamp.h>
39 #include <epan/prefs.h>
40 #include <epan/nstime.h>
41 #include <epan/dfilter/dfilter.h>
42 #include <epan/column.h>
43 #include <epan/packet.h>
44
45 /* Given a format number (as defined in column_info.h), returns its equivalent
46    string */
47 const gchar *
48 col_format_to_string(gint fmt) {
49   const gchar *slist[] = {
50     "%q",                                       /* 0) COL_8021Q_VLAN_ID */
51     "%Yt",                                      /* 1) COL_ABS_DATE_TIME */
52     "%At",                                      /* 2) COL_ABS_TIME */
53     "%c",                                       /* 3) COL_CIRCUIT_ID */
54     "%Xd",                                      /* 4) COL_DSTIDX */
55     "%Xs",                                      /* 5) COL_SRCIDX */
56     "%V",                                       /* 6) COL_VSAN */
57     "%B",                                       /* 7) COL_CUMULATIVE_BYTES */
58     "%Cus",                                     /* 8) COL_CUSTOM */
59     "%y",                                       /* 9) COL_DCE_CALL */
60     "%z",                                       /* 10) COL_DCE_CTX */
61     "%Tt",                                      /* 11) COL_DELTA_TIME */
62     "%dct",                                     /* 12) COL_DELTA_CONV_TIME */
63     "%Gt",                                      /* 13) COL_DELTA_TIME_DIS */
64     "%rd",                                      /* 14) COL_RES_DST */
65     "%ud",                                      /* 15) COL_UNRES_DST */
66     "%rD",                                      /* 16) COL_RES_DST_PORT */
67     "%uD",                                      /* 17) COL_UNRES_DST_PORT */
68     "%d",                                       /* 18) COL_DEF_DST */
69     "%D",                                       /* 19) COL_DEF_DST_PORT */
70     "%a",                                       /* 20) COL_EXPERT */
71     "%I",                                       /* 21) COL_IF_DIR */
72     "%XO",                                      /* 22) COL_OXID */
73     "%XR",                                      /* 23) COL_RXID */
74     "%C",                                       /* 24) !! DEPRECATED !! - COL_FR_DLCI */
75     "%F",                                       /* 25) COL_FREQ_CHAN */
76     "%l",                                       /* 26) !! DEPRECATED !! - COL_BSSGP_TLLI */
77     "%P",                                       /* 27) !! DEPRECATED !! - COL_HPUX_DEVID */
78     "%H",                                       /* 28) !! DEPRECATED !! - COL_HPUX_SUBSYS */
79     "%hd",                                      /* 29) COL_DEF_DL_DST */
80     "%hs",                                      /* 30) COL_DEF_DL_SRC */
81     "%rhd",                                     /* 31) COL_RES_DL_DST */
82     "%uhd",                                     /* 32) COL_UNRES_DL_DST */
83     "%rhs",                                     /* 33) COL_RES_DL_SRC*/
84     "%uhs",                                     /* 34) COL_UNRES_DL_SRC */
85     "%e",                                       /* 35) COL_RSSI */
86     "%x",                                       /* 36) COL_TX_RATE */
87     "%f",                                       /* 37) COL_DSCP_VALUE */
88     "%i",                                       /* 38) COL_INFO */
89     "%U",                                       /* 39) !! DEPRECATED !! - COL_COS_VALUE */
90     "%rnd",                                     /* 40) COL_RES_NET_DST */
91     "%und",                                     /* 41) COL_UNRES_NET_DST */
92     "%rns",                                     /* 42) COL_RES_NET_SRC */
93     "%uns",                                     /* 43) COL_UNRES_NET_SRC */
94     "%nd",                                      /* 44) COL_DEF_NET_DST */
95     "%ns",                                      /* 45) COL_DEF_NET_SRC */
96     "%m",                                       /* 46) COL_NUMBER */
97     "%L",                                       /* 47) COL_PACKET_LENGTH */
98     "%p",                                       /* 48) COL_PROTOCOL */
99     "%Rt",                                      /* 49) COL_REL_TIME */
100     "%rct",                                     /* 50) !! DEPRECATED !! - COL_REL_CONV_TIME */
101     "%s",                                       /* 51) COL_DEF_SRC */
102     "%S",                                       /* 52) COL_DEF_SRC_PORT */
103     "%rs",                                      /* 53) COL_RES_SRC */
104     "%us",                                      /* 54) COL_UNRES_SRC */
105     "%rS",                                      /* 55) COL_RES_SRC_PORT */
106     "%uS",                                      /* 56) COL_UNRES_SRC_PORT */
107     "%E",                                       /* 57) COL_TEI */
108     "%t"                                        /* 58) COL_CLS_TIME */
109   };
110
111   if (fmt < 0 || fmt >= NUM_COL_FMTS)
112     return NULL;
113
114   return(slist[fmt]);
115 }
116
117 /* Given a format number (as defined in column_info.h), returns its
118   description */
119 static const gchar *dlist[NUM_COL_FMTS] = {
120     "802.1Q VLAN id",                           /* 0) COL_8021Q_VLAN_ID */
121     "Absolute date and time",                   /* 1) COL_ABS_DATE_TIME */
122     "Absolute time",                            /* 2) COL_ABS_TIME */
123     "Circuit ID",                               /* 3) COL_CIRCUIT_ID */
124     "Cisco Dst PortIdx",                        /* 4) COL_DSTIDX */
125     "Cisco Src PortIdx",                        /* 5) COL_SRCIDX */
126     "Cisco VSAN",                               /* 6) COL_VSAN */
127     "Cumulative Bytes" ,                        /* 7) COL_CUMULATIVE_BYTES */
128     "Custom",                                   /* 8) COL_CUSTOM */
129     "DCE/RPC call (cn_call_id / dg_seqnum)",    /* 9) COL_DCE_CALL */
130     "DCE/RPC context ID (cn_ctx_id)",           /* 10) COL_DCE_CTX */
131     "Delta time",                               /* 11) COL_DELTA_TIME */
132     "Delta time (conversation)",                /* 12) COL_DELTA_CONV_TIME */
133     "Delta time displayed",                     /* 13) COL_DELTA_TIME_DIS */
134     "Dest addr (resolved)",                     /* 14) COL_RES_DST */
135     "Dest addr (unresolved)",                   /* 15) COL_UNRES_DST */
136     "Dest port (resolved)",                     /* 16) COL_RES_DST_PORT */
137     "Dest port (unresolved)",                   /* 17) COL_UNRES_DST_PORT */
138     "Destination address",                      /* 18) COL_DEF_DST */
139     "Destination port",                         /* 19) COL_DEF_DST_PORT */
140     "Expert Info Severity",                     /* 20) COL_EXPERT */
141     "FW-1 monitor if/direction",                /* 21) COL_IF_DIR */
142     "Fibre Channel OXID",                       /* 22) COL_OXID */
143     "Fibre Channel RXID",                       /* 23) COL_RXID */
144     "Frame Relay DLCI",                         /* 24) !! DEPRECATED !! - COL_FR_DLCI */
145     "Frequency/Channel",                        /* 25) COL_FREQ_CHAN */
146     "GPRS BSSGP TLLI",                          /* 26) !! DEPRECATED !! - COL_BSSGP_TLLI */
147     "HP-UX Device ID",                          /* 27) !! DEPRECATED !! - COL_HPUX_DEVID */
148     "HP-UX Subsystem",                          /* 28) !! DEPRECATED !! - COL_HPUX_SUBSYS */
149     "Hardware dest addr",                       /* 29) COL_DEF_DL_DST */
150     "Hardware src addr",                        /* 30) COL_DEF_DL_SRC */
151     "Hw dest addr (resolved)",                  /* 31) COL_RES_DL_DST */
152     "Hw dest addr (unresolved)",                /* 32) COL_UNRES_DL_DST */
153     "Hw src addr (resolved)",                   /* 33) COL_RES_DL_SRC*/
154     "Hw src addr (unresolved)",                 /* 34) COL_UNRES_DL_SRC */
155     "IEEE 802.11 RSSI",                         /* 35) COL_RSSI */
156     "IEEE 802.11 TX rate",                      /* 36) COL_TX_RATE */
157     "IP DSCP Value",                            /* 37) COL_DSCP_VALUE */
158     "Information",                              /* 38) COL_INFO */
159     "L2 COS Value (802.1p)",                    /* 39) !! DEPRECATED !! - COL_COS_VALUE */
160     "Net dest addr (resolved)",                 /* 40) COL_RES_NET_DST */
161     "Net dest addr (unresolved)",               /* 41) COL_UNRES_NET_DST */
162     "Net src addr (resolved)",                  /* 42) COL_RES_NET_SRC */
163     "Net src addr (unresolved)",                /* 43) COL_UNRES_NET_SRC */
164     "Network dest addr",                        /* 44) COL_DEF_NET_DST */
165     "Network src addr",                         /* 45) COL_DEF_NET_SRC */
166     "Number",                                   /* 46) COL_NUMBER */
167     "Packet length (bytes)" ,                   /* 47) COL_PACKET_LENGTH */
168     "Protocol",                                 /* 48) COL_PROTOCOL */
169     "Relative time",                            /* 49) COL_REL_TIME */
170     "Relative time (conversation)",             /* 50) !! DEPRECATED !! - COL_REL_CONV_TIME */
171     "Source address",                           /* 51) COL_DEF_SRC */
172     "Source port",                              /* 52) COL_DEF_SRC_PORT */
173     "Src addr (resolved)",                      /* 53) COL_RES_SRC */
174     "Src addr (unresolved)",                    /* 54) COL_UNRES_SRC */
175     "Src port (resolved)",                      /* 55) COL_RES_SRC_PORT */
176     "Src port (unresolved)",                    /* 56) COL_UNRES_SRC_PORT */
177     "TEI",                                      /* 57) COL_TEI */
178     "Time (format as specified)"                /* 58) COL_CLS_TIME */
179 };
180
181 const gchar *
182 col_format_desc(gint fmt) {
183   g_assert((fmt >= 0) && (fmt < NUM_COL_FMTS));
184   return(dlist[fmt]);
185 }
186
187 /* Marks each array element true if it can be substituted for the given
188    column format */
189 void
190 get_column_format_matches(gboolean *fmt_list, gint format) {
191
192   /* Get the obvious: the format itself */
193   if ((format >= 0) && (format < NUM_COL_FMTS))
194     fmt_list[format] = TRUE;
195
196   /* Get any formats lower down on the chain */
197   switch (format) {
198     case COL_DEF_SRC:
199       fmt_list[COL_RES_DL_SRC] = TRUE;
200       fmt_list[COL_RES_NET_SRC] = TRUE;
201       break;
202     case COL_RES_SRC:
203       fmt_list[COL_RES_DL_SRC] = TRUE;
204       fmt_list[COL_RES_NET_SRC] = TRUE;
205       break;
206     case COL_UNRES_SRC:
207       fmt_list[COL_UNRES_DL_SRC] = TRUE;
208       fmt_list[COL_UNRES_NET_SRC] = TRUE;
209       break;
210     case COL_DEF_DST:
211       fmt_list[COL_RES_DL_DST] = TRUE;
212       fmt_list[COL_RES_NET_DST] = TRUE;
213       break;
214     case COL_RES_DST:
215       fmt_list[COL_RES_DL_DST] = TRUE;
216       fmt_list[COL_RES_NET_DST] = TRUE;
217       break;
218     case COL_UNRES_DST:
219       fmt_list[COL_UNRES_DL_DST] = TRUE;
220       fmt_list[COL_UNRES_NET_DST] = TRUE;
221       break;
222     case COL_DEF_DL_SRC:
223       fmt_list[COL_RES_DL_SRC] = TRUE;
224       break;
225     case COL_DEF_DL_DST:
226       fmt_list[COL_RES_DL_DST] = TRUE;
227       break;
228     case COL_DEF_NET_SRC:
229       fmt_list[COL_RES_NET_SRC] = TRUE;
230       break;
231     case COL_DEF_NET_DST:
232       fmt_list[COL_RES_NET_DST] = TRUE;
233       break;
234     case COL_DEF_SRC_PORT:
235       fmt_list[COL_RES_SRC_PORT] = TRUE;
236       break;
237     case COL_DEF_DST_PORT:
238       fmt_list[COL_RES_DST_PORT] = TRUE;
239       break;
240     case COL_OXID:
241       fmt_list[COL_OXID] = TRUE;
242       break;
243     case COL_RXID:
244       fmt_list[COL_RXID] = TRUE;
245       break;
246     case COL_IF_DIR:
247       fmt_list[COL_IF_DIR] = TRUE;
248       break;
249     case COL_CIRCUIT_ID:
250       fmt_list[COL_CIRCUIT_ID] = TRUE;
251       break;
252     case COL_SRCIDX:
253       fmt_list[COL_SRCIDX] = TRUE;
254       break;
255     case COL_DSTIDX:
256       fmt_list[COL_DSTIDX] = TRUE;
257       break;
258     case COL_VSAN:
259       fmt_list[COL_VSAN] = TRUE;
260       break;
261     case COL_TX_RATE:
262       fmt_list[COL_TX_RATE] = TRUE;
263       break;
264     case COL_RSSI:
265       fmt_list[COL_RSSI] = TRUE;
266       break;
267     case COL_HPUX_SUBSYS:
268       fmt_list[COL_HPUX_SUBSYS] = TRUE;
269       break;
270     case COL_HPUX_DEVID:
271       fmt_list[COL_HPUX_DEVID] = TRUE;
272       break;
273     case COL_DCE_CALL:
274       fmt_list[COL_DCE_CALL] = TRUE;
275       break;
276     case COL_DCE_CTX:
277       fmt_list[COL_DCE_CTX] = TRUE;
278       break;
279     case COL_8021Q_VLAN_ID:
280       fmt_list[COL_8021Q_VLAN_ID] = TRUE;
281       break;
282     case COL_DSCP_VALUE:
283       fmt_list[COL_DSCP_VALUE] = TRUE;
284       break;
285     case COL_COS_VALUE:
286       fmt_list[COL_COS_VALUE] = TRUE;
287       break;
288     case COL_TEI:
289       fmt_list[COL_TEI] = TRUE;
290       break;
291     case COL_FR_DLCI:
292       fmt_list[COL_FR_DLCI] = TRUE;
293       break;
294     case COL_BSSGP_TLLI:
295       fmt_list[COL_BSSGP_TLLI] = TRUE;
296       break;
297     case COL_EXPERT:
298       fmt_list[COL_EXPERT] = TRUE;
299       break;
300     case COL_FREQ_CHAN:
301       fmt_list[COL_FREQ_CHAN] = TRUE;
302       break;
303     case COL_CUSTOM:
304       fmt_list[COL_CUSTOM] = TRUE;
305       break;
306     default:
307       break;
308   }
309 }
310
311 /* Returns a string representing the longest possible value for
312    a timestamp column type. */
313 static const char *
314 get_timestamp_column_longest_string(gint type, gint precision)
315 {
316
317     switch(type) {
318     case(TS_ABSOLUTE_WITH_DATE):
319         switch(precision) {
320             case(TS_PREC_AUTO_SEC):
321             case(TS_PREC_FIXED_SEC):
322                 return "0000-00-00 00:00:00";
323                 break;
324             case(TS_PREC_AUTO_DSEC):
325             case(TS_PREC_FIXED_DSEC):
326                 return "0000-00-00 00:00:00.0";
327                 break;
328             case(TS_PREC_AUTO_CSEC):
329             case(TS_PREC_FIXED_CSEC):
330                 return "0000-00-00 00:00:00.00";
331                 break;
332             case(TS_PREC_AUTO_MSEC):
333             case(TS_PREC_FIXED_MSEC):
334                 return "0000-00-00 00:00:00.000";
335                 break;
336             case(TS_PREC_AUTO_USEC):
337             case(TS_PREC_FIXED_USEC):
338                 return "0000-00-00 00:00:00.000000";
339                 break;
340             case(TS_PREC_AUTO_NSEC):
341             case(TS_PREC_FIXED_NSEC):
342                 return "0000-00-00 00:00:00.000000000";
343                 break;
344             default:
345                 g_assert_not_reached();
346         }
347             break;
348     case(TS_ABSOLUTE):
349         switch(precision) {
350             case(TS_PREC_AUTO_SEC):
351             case(TS_PREC_FIXED_SEC):
352                 return "00:00:00";
353                 break;
354             case(TS_PREC_AUTO_DSEC):
355             case(TS_PREC_FIXED_DSEC):
356                 return "00:00:00.0";
357                 break;
358             case(TS_PREC_AUTO_CSEC):
359             case(TS_PREC_FIXED_CSEC):
360                 return "00:00:00.00";
361                 break;
362             case(TS_PREC_AUTO_MSEC):
363             case(TS_PREC_FIXED_MSEC):
364                 return "00:00:00.000";
365                 break;
366             case(TS_PREC_AUTO_USEC):
367             case(TS_PREC_FIXED_USEC):
368                 return "00:00:00.000000";
369                 break;
370             case(TS_PREC_AUTO_NSEC):
371             case(TS_PREC_FIXED_NSEC):
372                 return "00:00:00.000000000";
373                 break;
374             default:
375                 g_assert_not_reached();
376         }
377         break;
378     case(TS_RELATIVE):  /* fallthrough */
379     case(TS_DELTA):
380     case(TS_DELTA_DIS):
381         switch(precision) {
382             case(TS_PREC_AUTO_SEC):
383             case(TS_PREC_FIXED_SEC):
384                 return "0000";
385                 break;
386             case(TS_PREC_AUTO_DSEC):
387             case(TS_PREC_FIXED_DSEC):
388                 return "0000.0";
389                 break;
390             case(TS_PREC_AUTO_CSEC):
391             case(TS_PREC_FIXED_CSEC):
392                 return "0000.00";
393                 break;
394             case(TS_PREC_AUTO_MSEC):
395             case(TS_PREC_FIXED_MSEC):
396                 return "0000.000";
397                 break;
398             case(TS_PREC_AUTO_USEC):
399             case(TS_PREC_FIXED_USEC):
400                 return "0000.000000";
401                 break;
402             case(TS_PREC_AUTO_NSEC):
403             case(TS_PREC_FIXED_NSEC):
404                 return "0000.000000000";
405                 break;
406             default:
407                 g_assert_not_reached();
408         }
409         break;
410     case(TS_EPOCH):
411         /* This is enough to represent 2^63 (signed 64-bit integer) + fractions */
412         switch(precision) {
413             case(TS_PREC_AUTO_SEC):
414             case(TS_PREC_FIXED_SEC):
415                 return "0000000000000000000";
416                 break;
417             case(TS_PREC_AUTO_DSEC):
418             case(TS_PREC_FIXED_DSEC):
419                 return "0000000000000000000.0";
420                 break;
421             case(TS_PREC_AUTO_CSEC):
422             case(TS_PREC_FIXED_CSEC):
423                 return "0000000000000000000.00";
424                 break;
425             case(TS_PREC_AUTO_MSEC):
426             case(TS_PREC_FIXED_MSEC):
427                 return "0000000000000000000.000";
428                 break;
429             case(TS_PREC_AUTO_USEC):
430             case(TS_PREC_FIXED_USEC):
431                 return "0000000000000000000.000000";
432                 break;
433             case(TS_PREC_AUTO_NSEC):
434             case(TS_PREC_FIXED_NSEC):
435                 return "0000000000000000000.000000000";
436                 break;
437             default:
438                 g_assert_not_reached();
439         }
440         break;
441     case(TS_NOT_SET):
442         return "0000.000000";
443         break;
444     default:
445         g_assert_not_reached();
446     }
447
448     /* never reached, satisfy compiler */
449     return "";
450 }
451
452 /* Returns the longer string of the column title or the hard-coded width of
453  * its contents for building the packet list layout. */
454 const gchar *
455 get_column_width_string(gint format, gint col)
456 {
457     if(strlen(get_column_longest_string(format)) >
458        strlen(get_column_title(col)))
459         return get_column_longest_string(format);
460     else
461         return get_column_title(col);
462 }
463
464 /* Returns a string representing the longest possible value for a
465    particular column type.  See also get_column_width_string() above.
466
467    Except for the COL...SRC and COL...DST columns, these are used
468    only when a capture is being displayed while it's taking place;
469    they are arguably somewhat fragile, as changes to the code that
470    generates them don't cause these widths to change, but that's
471    probably not too big a problem, given that the sizes are
472    recomputed based on the actual data in the columns when the capture
473    is done, and given that the width for COL...SRC and COL...DST columns
474    is somewhat arbitrary in any case.  We should probably clean
475    that up eventually, though. */
476 const char *
477 get_column_longest_string(gint format)
478 {
479   switch (format) {
480     case COL_NUMBER:
481       return "0000000";
482       break;
483     case COL_CLS_TIME:
484       return get_timestamp_column_longest_string(timestamp_get_type(), timestamp_get_precision());
485       break;
486     case COL_ABS_DATE_TIME:
487       return get_timestamp_column_longest_string(TS_ABSOLUTE_WITH_DATE, timestamp_get_precision());
488       break;
489     case COL_ABS_TIME:
490       return get_timestamp_column_longest_string(TS_ABSOLUTE, timestamp_get_precision());
491       break;
492     case COL_REL_TIME:
493       return get_timestamp_column_longest_string(TS_RELATIVE, timestamp_get_precision());
494       break;
495     case COL_DELTA_TIME:
496       return get_timestamp_column_longest_string(TS_DELTA, timestamp_get_precision());
497       break;
498     case COL_DELTA_TIME_DIS:
499       return get_timestamp_column_longest_string(TS_DELTA_DIS, timestamp_get_precision());
500       break;
501     case COL_REL_CONV_TIME: /* 'abuse' TS_RELATIVE to set the time format */
502     case COL_DELTA_CONV_TIME:   /* for the conversation related time columns */
503       return get_timestamp_column_longest_string(TS_RELATIVE, timestamp_get_precision());
504       break;
505     case COL_DEF_SRC:
506     case COL_RES_SRC:
507     case COL_UNRES_SRC:
508     case COL_DEF_DL_SRC:
509     case COL_RES_DL_SRC:
510     case COL_UNRES_DL_SRC:
511     case COL_DEF_NET_SRC:
512     case COL_RES_NET_SRC:
513     case COL_UNRES_NET_SRC:
514     case COL_DEF_DST:
515     case COL_RES_DST:
516     case COL_UNRES_DST:
517     case COL_DEF_DL_DST:
518     case COL_RES_DL_DST:
519     case COL_UNRES_DL_DST:
520     case COL_DEF_NET_DST:
521     case COL_RES_NET_DST:
522     case COL_UNRES_NET_DST:
523       return "00000000.000000000000"; /* IPX-style */
524       break;
525     case COL_DEF_SRC_PORT:
526     case COL_RES_SRC_PORT:
527     case COL_UNRES_SRC_PORT:
528     case COL_DEF_DST_PORT:
529     case COL_RES_DST_PORT:
530     case COL_UNRES_DST_PORT:
531       return "000000";
532       break;
533     case COL_PROTOCOL:
534       return "Protocol";    /* not the longest, but the longest is too long */
535       break;
536     case COL_PACKET_LENGTH:
537       return "00000";
538       break;
539     case COL_CUMULATIVE_BYTES:
540       return "00000000";
541       break;
542     case COL_RXID:
543     case COL_OXID:
544       return "000000";
545       break;
546     case COL_IF_DIR:
547       return "i 00000000 I";
548       break;
549     case COL_CIRCUIT_ID:
550       return "000000";
551       break;
552     case COL_SRCIDX:
553     case COL_DSTIDX:
554       return "0000000";
555       break;
556     case COL_VSAN:
557      return "000000";
558       break;
559     case COL_TX_RATE:
560       return "108.0";
561       break;
562     case COL_RSSI:
563       return "100";
564       break;
565     case COL_HPUX_SUBSYS:
566       return "OTS9000-TRANSPORT";
567       break;
568     case COL_HPUX_DEVID:
569       return "0000";
570       break;
571     case COL_DCE_CALL:
572       return "0000";
573       break;
574     case COL_DCE_CTX:
575       return "0000";
576       break;
577     case COL_8021Q_VLAN_ID:
578       return "0000";
579       break;
580     case COL_DSCP_VALUE:
581       return "00";
582       break;
583     case COL_COS_VALUE:
584       return "0";
585       break;
586     case COL_TEI:
587       return "127";
588       break;
589     case COL_FR_DLCI:
590       return "8388608";
591       break;
592     case COL_BSSGP_TLLI:
593       return "0xffffffff";
594       break;
595     case COL_EXPERT:
596       return "ERROR";
597       break;
598     case COL_FREQ_CHAN:
599       return "9999 MHz [A 999]";
600       break;
601     case COL_CUSTOM:
602       return "0000000000";  /* not the longest, but the longest is too long */
603       break;
604     default: /* COL_INFO */
605       return "Source port: kerberos-master  Destination port: kerberos-master";
606       break;
607   }
608 }
609
610 /* Returns the longest possible width, in characters, for a particular
611    column type. */
612 gint
613 get_column_char_width(gint format)
614 {
615   return (gint)strlen(get_column_longest_string(format));
616 }
617
618 gint
619 get_column_format(gint col)
620 {
621   GList    *clp = g_list_nth(prefs.col_list, col);
622   fmt_data *cfmt;
623
624   if (!clp)  /* Invalid column requested */
625     return -1;
626
627   cfmt = (fmt_data *) clp->data;
628
629   return(get_column_format_from_str(cfmt->fmt));
630 }
631
632 gint
633 get_column_format_from_str(gchar *str)
634 {
635   gint i;
636
637   for (i = 0; i < NUM_COL_FMTS; i++) {
638     if (strcmp(str, col_format_to_string(i)) == 0)
639       return i;
640   }
641   return -1;    /* illegal */
642 }
643
644 gchar *
645 get_column_title(gint col)
646 {
647   GList    *clp = g_list_nth(prefs.col_list, col);
648   fmt_data *cfmt;
649
650   if (!clp)  /* Invalid column requested */
651     return NULL;
652
653   cfmt = (fmt_data *) clp->data;
654
655   return(cfmt->title);
656 }
657
658 const gchar *
659 get_column_custom_field(gint col)
660 {
661   GList    *clp = g_list_nth(prefs.col_list, col);
662   fmt_data *cfmt;
663
664   if (!clp)  /* Invalid column requested */
665     return NULL;
666
667   cfmt = (fmt_data *) clp->data;
668
669   return(cfmt->custom_field);
670 }
671
672 void
673 build_column_format_array(column_info *cinfo, gint num_cols, gboolean reset_fences)
674 {
675   int i;
676
677   /* Build the column format array */
678   col_setup(cinfo, num_cols);
679
680   for (i = 0; i < cinfo->num_cols; i++) {
681     cinfo->col_fmt[i] = get_column_format(i);
682     cinfo->col_title[i] = g_strdup(get_column_title(i));
683
684     if (cinfo->col_fmt[i] == COL_CUSTOM) {
685       cinfo->col_custom_field[i] = g_strdup(get_column_custom_field(i));
686       if(!dfilter_compile(cinfo->col_custom_field[i], &cinfo->col_custom_dfilter[i])) {
687         /* XXX: Should we issue a warning? */
688         g_free(cinfo->col_custom_field[i]);
689         cinfo->col_custom_field[i] = NULL;
690         cinfo->col_custom_dfilter[i] = NULL;
691       }
692     } else {
693       cinfo->col_custom_field[i] = NULL;
694       cinfo->col_custom_dfilter[i] = NULL;
695     }
696
697     cinfo->fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) * NUM_COL_FMTS);
698     get_column_format_matches(cinfo->fmt_matx[i], cinfo->col_fmt[i]);
699     cinfo->col_data[i] = NULL;
700
701     if (cinfo->col_fmt[i] == COL_INFO)
702       cinfo->col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
703     else
704       cinfo->col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
705
706     if(reset_fences)
707       cinfo->col_fence[i] = 0;
708
709     cinfo->col_expr.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
710     cinfo->col_expr.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
711   }
712
713   cinfo->col_expr.col_expr[i] = NULL;
714   cinfo->col_expr.col_expr_val[i] = NULL;
715
716   for (i = 0; i < cinfo->num_cols; i++) {
717     int j;
718
719     for (j = 0; j < NUM_COL_FMTS; j++) {
720       if (!cinfo->fmt_matx[i][j])
721           continue;
722
723       if (cinfo->col_first[j] == -1)
724         cinfo->col_first[j] = i;
725
726       cinfo->col_last[j] = i;
727     }
728   }
729 }