aboutsummaryrefslogtreecommitdiff
path: root/gfsm/gfsm/src/libgfsm/tests/priotest.c
blob: c56a39efc88b74d6d9b95e7de2a4cbe1dae52a13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <glib.h>
#include <stdio.h>
#include <string.h>

const char *prog=NULL;

//======================================================================
// typedefs
typedef enum {
  gfsmAFNone    = 0x0,  /**< no sort field */
  gfsmAFLower   = 0x1,  /**< sort by lower label */
  gfsmAFUpper   = 0x2,  /**< sort by upper label */
  gfsmAFWeight  = 0x3,  /**< sort by weight (refers to semiring) */
  gfsmAFSource  = 0x4,  /**< sort by arc source (if supported and meaningful) */
  gfsmAFTarget  = 0x5,  /**< sort by arc target (if supported and meaningful) */
  gfsmAFUser    = 0x6,  /**< user-defined sort function */
  gfsmAFAll     = 0x7,  /**< not really a sort field: mask of all valid sort fields */
  gfsmAFReverse = 0x8,  /**< not really a sort field: if set, indicates that arc comparisons should be reversed */
  gfsmAFMask    = 0xf   /**< not really a sort field: mask of valid sort fields & reverse flag */
} gfsmArcField;

typedef enum {
  gfsmAFNone    = 0x0,  /**< '_': no sort field */
  gfsmAFLower   = 0x1,  /**< 'l': sort by lower label */
  gfsmAFUpper   = 0x2,  /**< 'u': sort by upper label */
  gfsmAFWeight  = 0x3,  /**< 'w': sort by weight (refers to semiring) */
  gfsmAFSource  = 0x4,  /**< 's': sort by arc source (if supported and meaningful) */
  gfsmAFTarget  = 0x5,  /**< 't': sort by arc target (if supported and meaningful) */
  gfsmAFLowerR  = 0x6,  /**< 'L': reverse sort by lower label */
  gfsmAFUpperR  = 0x7,  /**< 'U': reverse sort by upper label */
  gfsmAFWeightR = 0x8,  /**< 'W': reverse sort semiring weight */
  gfsmAFSourceR = 0x9,  /**< 'S': reverse sort source state (if supported and meaningful) */
  gfsmAFTargetR = 0xa,  /**< 'T': reverse sort target state (if supported and meaningful) */
  gfsmAFUser    = 0xf   /**< 'x': pseudo-field for user-defined comparisons */
} gfsmArcFieldId;

#define gfsmArcFieldShift 4       //-- number of bits in a single logical ::gfsmArcField element
const guint32 gfsmNArcFields = 5; //-- maximum 'nth' paramter supported by ::gfsmArcFieldMask

typedef guint32 gfsmArcFieldMask; //-- mask of ::gfsmArcField values, left-shifted by ::gfsmArcFieldShift


const guint32 gfsmAFM_L   = gfsmAFLower;
const guint32 gfsmAFM_LU  = gfsmAFLower|(gfsmAFUpper<<gfsmArcFieldShift);
const guint32 gfsmAFM_LUW = gfsmAFLower|(gfsmAFUpper<<gfsmArcFieldShift)|(gfsmAFWeight<<(2*gfsmArcFieldShift));

gfsmArcFieldMask gfsm_arc_field_mask_new(guint nth, gfsmArcField field, gboolean reverse)
{
  gfsmArcFieldMask m = field;
  if (reverse) m |= gfsmAFReverse;
  return m << (nth*gfsmArcFieldShift);
}

gfsmArcFieldMask gfsm_arc_field_mask_add(gfsmArcFieldMask m, guint nth, gfsmArcField field, gboolean reverse)
{ return (m | gfsm_arc_field_mask_new(nth,field,reverse)); }

gfsmArcFieldMask gfsm_arc_field_mask_clear(gfsmArcFieldMask m, guint nth)
{ return m & ((~gfsmAFMask)<<(nth*gfsmArcFieldShift)); }

gfsmArcField gfsm_arc_field_mask_get_field(gfsmArcFieldMask m, guint nth)
{ return (m>>(nth*gfsmArcFieldShift))&gfsmAFAll; }

gboolean gfsm_arc_field_mask_get_reverse(gfsmArcFieldMask m, guint nth)
{ return ((m>>(nth*gfsmArcFieldShift))&gfsmAFReverse) ? TRUE : FALSE; }


//======================================================================
// parse
gfsmArcFieldMask parse_mask(const char *str)
{
  gfsmArcFieldMask m = 0;
  gint i;
  guint nth=0;
  /*
  gint   max_tokens = 32;
  gchar **toks = g_strsplit(str,",; \n\t",max_tokens);

  //-- parse
  for (i=0; toks[i] != NULL; i++) {
    gchar *tok = toks[i];
    g_strstrip(tok);
  }
  */
  for (i=0; str[i] && nth < gfsmNArcFields; i++) {
    switch (str[i]) {
    case 'l' : m |= gfsm_arc_field_mask_new(nth++,gfsmAFLower,0); break;
    case 'L' : m |= gfsm_arc_field_mask_new(nth++,gfsmAFLower,1); break;

    case 'u' : m |= gfsm_arc_field_mask_new(nth++,gfsmAFUpper,0); break;
    case 'U' : m |= gfsm_arc_field_mask_new(nth++,gfsmAFUpper,1); break;

    case 'w' : m |= gfsm_arc_field_mask_new(nth++,gfsmAFWeight,0); break;
    case 'W' : m |= gfsm_arc_field_mask_new(nth++,gfsmAFWeight,1); break;

    case 's' : m |= gfsm_arc_field_mask_new(nth++,gfsmAFSource,0); break;
    case 'S' : m |= gfsm_arc_field_mask_new(nth++,gfsmAFSource,1); break;

    case 't' : m |= gfsm_arc_field_mask_new(nth++,gfsmAFTarget,0); break;
    case 'T' : m |= gfsm_arc_field_mask_new(nth++,gfsmAFTarget,1); break;

      //-- silently ignore these
    case 'x':
    case 'X':
    case '-':
    case ',':
    case ' ':
    case '\t':
    case '\n':
      break;

    default:
      g_printerr("%s: character '%c' is not in [sStTlLuUwW] in field string '%s' - skipping\n", prog, str[i], str);
      break;
    }
  }
  if (str[i] && nth==gfsmNArcFields) {
    g_printerr("%s: ignoring trailing characters '%s' in field string '%s'\n", prog, (str+i), str);
  }
  
  //-- cleanup
  //g_strfreev(toks);

  return m;
}

//======================================================================
// dump

const char *mask_field_str(gfsmArcFieldMask afm, guint nth)
{
  switch (gfsm_arc_field_mask_get_field(afm, nth)) {
  case gfsmAFNone:    return "none";
  case gfsmAFLower:   return "lower";
  case gfsmAFUpper:   return "upper";
  case gfsmAFWeight:  return "weight";
  case gfsmAFSource:  return "source";
  case gfsmAFTarget:  return "target";
  default: return "?";
  }
  return "?";
}
const char *mask_reverse_str(gfsmArcFieldMask afm, guint nth)
{
  return gfsm_arc_field_mask_get_reverse(afm, nth) ? ">" : "<";
}

void dump_mask(gfsmArcFieldMask afm, const char *str)
{
  printf("%s: str='%s': priorities = %u = %#0.6x = { %s%s, %s%s, %s%s, %s%s, %s%s }\n",
	 prog, str, afm, afm,
	 mask_field_str(afm,0), mask_reverse_str(afm,0),
	 mask_field_str(afm,1), mask_reverse_str(afm,1),
	 mask_field_str(afm,2), mask_reverse_str(afm,2),
	 mask_field_str(afm,3), mask_reverse_str(afm,3),
	 mask_field_str(afm,4), mask_reverse_str(afm,4)
	 );
}

//======================================================================
// MAIN
int main(int argc, char **argv) {
  int i;
  gfsmArcFieldMask afm = 0;

  prog = argv[0];
  for (i=1; i < argc; i++) {
    afm = parse_mask(argv[i]);
    dump_mask(afm, argv[i]);
  }
  return 0;
}