00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdio.h>
00012 #include "med.h"
00013
00014 extern int debug;
00015
00016
00017 int prefix (char *s1, char *s2)
00018
00019
00020
00021 {
00022 while ((*s1) && (*s2) && (*s1==*s2)) {
00023 s1++;
00024 s2++;
00025 }
00026 return (!*s1);
00027 }
00028
00029
00030 static void upstring(char *s)
00031
00032
00033
00034 {
00035 while (*s) {
00036 if ((*s >= 'a') && (*s <= 'z'))
00037 *s = *s - 'a' + 'A';
00038 s++;
00039 }
00040 }
00041
00042
00043 static void stripwhitespace(char *s)
00044
00045
00046
00047 {
00048 char *r = s;
00049
00050 while (*s) {
00051 if ((*s!=' ') && (*s!='\t') && (*s!='\n')) {
00052 *r=*s;
00053 r++;
00054 }
00055 s++;
00056 }
00057 *r='\0';
00058 }
00059
00060
00061 static int balanced(char *s)
00062
00063
00064
00065 {
00066 int leftbraces=0,rightbraces=0;
00067 int good=1;
00068 while (*s) {
00069 if (*s=='{')
00070 leftbraces++;
00071 else if (*s=='}')
00072 rightbraces++;
00073 if (rightbraces > leftbraces)
00074 good = 0;
00075 s++;
00076 }
00077 return((good) && (leftbraces==rightbraces));
00078 }
00079
00080
00081 static int atom(char *s)
00082
00083
00084
00085 {
00086 int leftbraces=0;
00087 while ((*s) && (*s != '}')) {
00088 if (*s=='{')
00089 leftbraces++;
00090 s++;
00091 }
00092 return(leftbraces==1);
00093 }
00094
00095
00096
00097 static char *advance_past_comma(char *s)
00098
00099
00100
00101 {
00102 int paren=0;
00103 while (*s) {
00104 if (*s=='{')
00105 paren++;
00106 else if (*s=='}')
00107 paren--;
00108 else if ((*s==',') && (paren==0)) {
00109 s++;
00110 break;
00111 }
00112 s++;
00113 }
00114 return (s);
00115 }
00116
00117
00118 static med *new_med(void)
00119 {
00120 med *bob = (med *) malloc(sizeof(med));
00121 if (bob==NULL) {
00122 fflush(stdout);
00123 fprintf(stderr, "new_med(): malloc() returned NULL.\n");
00124 exit(1);
00125 }
00126 return(bob);
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136 static int depth;
00137 static int gotucf;
00138
00139 static void check_med1(med *m)
00140 {
00141 depth++;
00142 while (m != NULL) {
00143 if (m->type == MedList)
00144 check_med1(m->list);
00145 if (m->rc == UCF) {
00146 if (gotucf) {
00147 fflush(stdout);
00148 fprintf(stderr, "check_med1(): Multiple 'RC UCF's are not allowed.\n");
00149 exit(1);
00150 }
00151 else {
00152 gotucf=1;
00153 }
00154 if (depth > 1) {
00155 fflush(stdout);
00156 fprintf(stderr, "check_med1(): 'RC UCF's not allowed in a nested sub-expression.\n");
00157 exit(1);
00158 }
00159 }
00160 m = m->next;
00161 }
00162 depth--;
00163 }
00164
00165 static void check_med(med *m)
00166
00167
00168
00169
00170 {
00171 depth=0;
00172 gotucf=0;
00173
00174 check_med1(m);
00175
00176 while (m->next != NULL) {
00177 m = m->next;
00178 }
00179
00180 if ((m->next == NULL) && (m->rc != UCF)) {
00181 printf("check_med(): Last entry in MultiplexEntryDescriptor should contain a 'RC UCF'.\n");
00182 exit(1);
00183 }
00184 }
00185
00186
00187
00188
00189
00190
00191
00192 static med *parse_med1(char *s)
00193
00194
00195
00196
00197
00198
00199
00200
00201 {
00202 int i=0, paren=0;
00203 char *r, *t;
00204 med *head, *bob;
00205
00206
00207
00208
00209
00210
00211 s++;
00212 if (*s == '{') {
00213
00214
00215
00216 head = new_med();
00217 head->type = MedList;
00218 head->next = NULL;
00219
00220 head->list = bob = parse_med1(s);
00221
00222 s = advance_past_comma(s);
00223
00224 while (*s == '{') {
00225 bob->next = parse_med1(s);
00226 bob = bob->next;
00227 bob->next = NULL;
00228
00229 s = advance_past_comma(s);
00230 }
00231
00232 if (prefix("RCUCF", s)) {
00233 head->rc = UCF;
00234 }
00235 else if (prefix("RC", s)) { head->rc = atoi(s+2);
00236 }
00237 else {
00238 fflush(stdout);
00239 fprintf(stderr, "parse_med1(): Parse error at %s.\n", s);
00240 exit(1);
00241 }
00242 }
00243
00244 else {
00245 if (prefix("LCN", s)) {
00246 head = new_med();
00247 s+=3;
00248 head->type = MedAtom;
00249 head->ch = atoi(s);
00250 head->next = NULL;
00251
00252 s = advance_past_comma(s);
00253 if (prefix("RCUCF", s)) {
00254 head->rc = UCF;
00255 }
00256 else if (prefix("RC", s)) {
00257 head->rc = atoi(s+2);
00258 }
00259 else {
00260 fflush(stdout);
00261 fprintf(stdout,"parse_med1(): Parse_error at %s.\n", s);
00262 exit(1);
00263 }
00264 }
00265 else {
00266 fflush(stdout);
00267 fprintf(stderr,"parse_med1(): Parse error at %s.\n", s);
00268 exit(1);
00269 }
00270 }
00271 return (head);
00272 }
00273
00274
00275 static med *parse_med(char *s)
00276
00277
00278
00279
00280
00281 {
00282 med *bob, *alice;
00283
00284 upstring(s);
00285 stripwhitespace(s);
00286
00287 if (!balanced(s)) {
00288 printf("Error: Unbalanced {}'s.\n");
00289 }
00290
00291 if (*s != '{') {
00292 fflush(stdout);
00293 fprintf(stderr, "parse_med(): Parse error at %s.\n", s);
00294 exit(1);
00295 }
00296 bob = alice = parse_med1(s);
00297
00298 s = advance_past_comma(s);
00299
00300 while (*s) {
00301 alice->next = parse_med1(s);
00302 alice = alice->next;
00303 alice->next = NULL;
00304 s = advance_past_comma(s);
00305 }
00306
00307 check_med(bob);
00308 return(bob);
00309 }
00310
00311
00312 static void print_med(med *m)
00313
00314
00315
00316
00317
00318 {
00319 while (m != NULL) {
00320 printf("{");
00321 if (m->type == MedAtom) {
00322 printf("LCN%d", m->ch);
00323 }
00324 else {
00325 print_med(m->list);
00326 }
00327 if (m->rc == -1)
00328 printf(",RC UCF}");
00329 else
00330 printf(",RC %d}", m->rc);
00331 if (m->next != NULL)
00332 printf(",");
00333 m = m->next;
00334 }
00335 }
00336
00337
00338 static void print_sample(med *m)
00339
00340
00341
00342
00343
00344
00345
00346 {
00347 int i;
00348
00349 while (m) {
00350 if (m->type == MedAtom) {
00351 if (m->rc == UCF) {
00352 printf("{%d} repeat until closing flag", m->ch);
00353 }
00354 else {
00355 for (i=0;i<m->rc;i++) {
00356 printf("%d", m->ch);
00357 }
00358 }
00359 }
00360 else if (m->type == MedList) {
00361 if (m->rc == UCF) {
00362 printf("{");
00363 print_sample(m->list);
00364 printf("} repeat until closing flag");
00365 }
00366 else {
00367 for (i=0; i<m->rc; i++) {
00368 print_sample(m->list);
00369 }
00370 }
00371 }
00372 m = m->next;
00373 }
00374 }
00375
00376
00377 static int figure_length1(med *m)
00378
00379
00380
00381
00382
00383 {
00384 int sum=0;
00385 while (m != NULL) {
00386 if (m->type == MedAtom) {
00387 sum += m->rc;
00388 }
00389 else {
00390 sum += m->rc * figure_length1(m->list);
00391 }
00392 m = m->next;
00393 }
00394 return (sum);
00395 }
00396
00397 static int figure_length(med *m)
00398
00399
00400
00401
00402 {
00403 int sum=0;
00404 if (m->type == MedAtom) {
00405 if (m->rc == UCF)
00406 sum = 1;
00407 else
00408 sum = m->rc;
00409 }
00410 else {
00411 if (m->rc == UCF) {
00412 sum += figure_length1(m->list);
00413 }
00414 else {
00415 sum += m->rc * figure_length1(m->list);
00416 }
00417 }
00418 return(sum);
00419 }
00420
00421
00422 static void write_pattern1(int *pattern, int *offset, med *m)
00423
00424
00425
00426
00427 {
00428 int i;
00429 while (m != NULL) {
00430 if (m->type == MedAtom) {
00431 if (m->rc == UCF) {
00432 pattern[(*offset)++]=m->ch;
00433 }
00434 else {
00435 for (i=0; i<m->rc; i++)
00436 pattern[(*offset)++]=m->ch;
00437 }
00438 }
00439 else if (m->type == MedList) {
00440 if (m->rc == UCF) {
00441 write_pattern1(pattern, offset, m->list);
00442 }
00443 else {
00444 for (i=0; i<m->rc; i++)
00445 write_pattern1(pattern, offset, m->list);
00446 }
00447 }
00448 m = m->next;
00449 }
00450 }
00451
00452
00453 static void write_pattern(int *pattern, int *offset, med *m)
00454
00455
00456
00457
00458 {
00459 int i;
00460
00461 if (m->type == MedAtom) {
00462 if (m->rc == UCF) {
00463 pattern[(*offset)++]=m->ch;
00464 }
00465 else {
00466 for (i=0; i<m->rc; i++)
00467 pattern[(*offset)++]=m->ch;
00468 }
00469 }
00470 else if (m->type == MedList) {
00471 if (m->rc == UCF) {
00472 write_pattern1(pattern, offset, m->list);
00473 }
00474 else {
00475 for (i=0; i<m->rc; i++)
00476 write_pattern1(pattern, offset, m->list);
00477 }
00478 }
00479 }
00480
00481
00482
00483 static med_pattern *make_pattern(med *m)
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 {
00499 med_pattern *pat;
00500 med *save_m;
00501 int x, y;
00502
00503 pat = (med_pattern *) malloc(sizeof(med_pattern));
00504 if (debug)
00505 printf("make_pattern at %x...............................................\n",pat);
00506 if (pat == NULL) {
00507
00508
00509
00510 warn("make_pattern", "malloc failed");
00511 }
00512 else {
00513
00514
00515
00516 pat->non_repeating_part_length = 0;
00517 pat->non_repeating_part = NULL;
00518 pat->repeating_part_length = 0;
00519 pat->repeating_part = NULL;
00520 save_m = m;
00521 while (m != NULL) {
00522 if (m->rc != UCF)
00523 pat->non_repeating_part_length += figure_length(m);
00524 else
00525 pat->repeating_part_length += figure_length(m);
00526
00527 m = m->next;
00528 }
00529 pat->non_repeating_part = (int *) malloc(pat->non_repeating_part_length * sizeof(int));
00530 pat->repeating_part = (int *) malloc(pat->repeating_part_length * sizeof(int));
00531
00532 if (((pat->non_repeating_part == NULL)&&(pat->non_repeating_part_length>0)) ||
00533 ((pat->repeating_part == NULL)&&(pat->repeating_part_length>0))) {
00534 warn("make_pattern", "malloc failed");
00535 }
00536 else {
00537 m = save_m;
00538 x = 0;
00539 y = 0;
00540 while (m != NULL) {
00541 if (m->rc != UCF) {
00542 write_pattern(pat->non_repeating_part, &x, m);
00543 }
00544 else {
00545 write_pattern(pat->repeating_part, &y, m);
00546 }
00547 m = m->next;
00548 }
00549 }
00550 }
00551 return (pat);
00552 }
00553
00554
00555 static void print_pattern(med_pattern *pat)
00556 {
00557 int i;
00558 printf("non-repeating part length: %d\n", pat->non_repeating_part_length);
00559 printf("non-repeating part: ");
00560 for (i=0; i<pat->non_repeating_part_length; i++)
00561 printf("%d", pat->non_repeating_part[i]);
00562 printf("\n");
00563 printf("repeating part length: %d\n", pat->repeating_part_length);
00564 printf("repeating part : ");
00565 for (i=0; i<pat->repeating_part_length; i++)
00566 printf("%d", pat->repeating_part[i]);
00567 printf("\n");
00568 }
00569
00570
00571
00572 void add_to_mux_table(mux_table_entry *mt, int *size, char *medstr)
00573 {
00574 mt[*size].entry = parse_med(medstr);
00575 mt[*size].pattern = make_pattern(mt[*size].entry);
00576
00577 if (debug)
00578 print_pattern(mt[*size].pattern);
00579
00580 (*size)++;
00581 }
00582