/* * regrepeat - repeatedly match something simple, report how many */ static i4 regrepeat(char *p) { register i4 count = 0; register char *scan; register char *opnd; scan = reginput; opnd = OPERAND(p); switch (OP(p)) { case ANY: count = STlength(scan); scan += count; break; case EXACTLY: while (*opnd == *scan) { CMbyteinc( count, scan ); CMnext( scan ); } break; case ANYOF: while (*scan != '\0' && STchr(opnd, *scan) != NULL) { CMbyteinc( count, scan ); CMnext( scan ); } break; case ANYBUT: while (*scan != '\0' && STchr(opnd, *scan) == NULL) { CMbyteinc( count, scan ); CMnext( scan ); } break; default: /* Oh dear. Called inappropriately. */ _error("internal foulup"); count = 0; /* Best compromise. */ break; } reginput = scan; return(count); }
/* * regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. */ static i4 /* 0 failure, 1 success */ regmatch(char *prog) { register char *scan; /* Current node. */ char *next; /* Next node. */ scan = prog; #ifdef xDEBUG if (scan != NULL && regnarrate) SIfprintf(stderr, "%s(\n", regprop(scan)); #endif while (scan != NULL) { #ifdef xDEBUG if (regnarrate) SIfprintf(stderr, "%s...\n", regprop(scan)); #endif next = regnext(scan); switch (OP(scan)) { case BOL: if (reginput != regbol) return(0); break; case EOL: if (*reginput != '\0') return(0); break; case ANY: if (*reginput == '\0') return(0); CMnext( reginput ); break; case EXACTLY: { register i4 len; register char *opnd; opnd = OPERAND(scan); /* Inline the first character, for speed. */ if (*opnd != *reginput) return(0); len = STlength(opnd); if (len > 1 && STncmp( opnd, reginput, len ) != 0 ) return(0); reginput += len; } break; case ANYOF: if (*reginput == '\0' || STchr(OPERAND(scan), *reginput) == NULL ) return(0); CMnext( reginput ); break; case ANYBUT: if (*reginput == '\0' || STchr(OPERAND(scan), *reginput) != NULL ) return(0); CMnext( reginput ); break; case NOTHING: break; case BACK: break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: { register i4 no; register char *save; no = OP(scan) - OPEN; save = reginput; if (regmatch(next)) { /* * Don't set startp if some later * invocation of the same parentheses * already has. */ if (regstartp[no] == NULL) regstartp[no] = save; return(1); } else return(0); } break; case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: { register i4 no; register char *save; no = OP(scan) - CLOSE; save = reginput; if (regmatch(next)) { /* * Don't set endp if some later * invocation of the same parentheses * already has. */ if (regendp[no] == NULL) regendp[no] = save; return(1); } else return(0); } break; case BRANCH: { register char *save; if (OP(next) != BRANCH) /* No choice. */ next = OPERAND(scan); /* Avoid recursion. */ else { do { save = reginput; if (regmatch(OPERAND(scan))) return(1); reginput = save; scan = regnext(scan); } while (scan != NULL && OP(scan) == BRANCH); return(0); /* NOTREACHED */ } } break; case STAR: case PLUS: { register char nextch; register i4 no; register char *save; register i4 minx; /* * Lookahead to avoid useless match attempts * when we know what character comes next. */ nextch = '\0'; if (OP(next) == EXACTLY) nextch = *OPERAND(next); minx = (OP(scan) == STAR) ? 0 : 1; save = reginput; no = regrepeat(OPERAND(scan)); while (no >= minx) { /* If it could work, try it. */ if (nextch == '\0' || *reginput == nextch) if (regmatch(next)) return(1); /* Couldn't or didn't -- back up. */ no--; reginput = save + no; } return(0); } break; case END: return(1); /* Success! */ break; default: _error("memory corruption"); return(0); break; } scan = next; } /* * We get here only if there's trouble -- normally "case END" is * the terminating point. */ _error("corrupted pointers"); return(0); }
/* * REexec - match a RE_EXP against a string */ bool REexec( RE_EXP *prog, char *string) { register char *s; /* Be paranoid... */ if (prog == NULL || string == NULL) { _error("NULL parameter"); return( FALSE ); } /* Check validity of program. */ if (UCHARAT(prog->program) != MAGIC) { _error("corrupted program"); return( FALSE ); } /* If there is a "must appear" string, look for it. */ if (prog->regmust != NULL) { s = string; while ((s = STchr(s, *prog->regmust)) != NULL) { if (STncmp( s, prog->regmust, prog->regmlen ) == 0 ) break; /* Found it. */ CMnext( s ); } if (s == NULL) /* Not present. */ return( FALSE ); } /* Mark beginning of line for ^ . */ regbol = string; /* Simplest case: anchored match need be tried only once. */ if (prog->reganch) return(regtry(prog, string)); /* Messy cases: unanchored match. */ s = string; if (prog->regstart != '\0') /* We know what char it must start with. */ while ((s = STchr(s, prog->regstart)) != NULL) { if (regtry(prog, s)) return( TRUE ); CMnext( s ); } else /* We don't -- general case. */ while( TRUE ) { if (regtry(prog, s)) return( TRUE ); if( *s == '\0' ) break; CMnext( s ); } # ifndef DOUBLEBYTE CMnext( s ); # else /* CMnext( s ); */ # endif /* #ifndef DOUBLEBYTE */ /* Failure. */ return( FALSE ); }
static STATUS TMtz_getopt( i4 nargc, char **nargv, char *ostr, i4 *ioptind, char *ioptarg, char *ioptopt) { char *place=""; /* option letter processing */ char *oli; /* option letter list index */ if (*ioptind >= nargc || *(place = nargv[*ioptind]) != '-' || !*++place) return(OK); if (*place == '-') { /* found "--" */ *ioptind += 1; return(OK); } if ((*ioptopt = *place++) == ':' || ((oli = STchr(ostr, *ioptopt)) == NULL)) { if (!*place) *ioptind += 1; SIprintf("%s: illegal option -- \n", appname); return(FAIL); } if (*++oli != ':') { /* don't need argument */ ioptarg = NULL; if (!*place) *ioptind += 1; } else { /* need an argument */ if (*place) { while(*place != '=' && *place != ' ') { if( *place == EOS) { if (nargc > (*ioptind += 1)) STcopy(nargv[*ioptind], ioptarg); else { *ioptopt = ' '; ioptarg = ""; } break; } place++; } STcopy(place+1, ioptarg); } else if (nargc <= (*ioptind += 1)) { /* no arg */ place = ""; ioptarg = ""; *ioptopt = ' '; } else /* white space */ STcopy(nargv[*ioptind], ioptarg); place = ""; *ioptind += 1; } return(OK); /* dump back option letter */ }
i4 main( i4 argc, char * argv[]) { char c='\0'; char *tz_file=NULL; char *tz_name=NULL; char *tz_def; char tzname[TM_MAX_TZNAME+1]; char tzfile[MAX_LOC+1]; char ioptarg[MAX_LOC + 1]; char tz_pmvalue[MAX_LOC + 1]; char tz_pmname[MAX_LOC + 1]; char *p, *ip, *pm_value; char *tm_tztype; char chr='/'; char *out_file; i4 ioptind=1, i; char *tm_tztime; i4 timecnt, tempi, temptype, temptz; char buf[sizeof(TM_TZ_CB)+TM_MAX_TIMECNT*(sizeof(i4)+1)]; FILE *fid; LOCATION loc_root, tmp_loc; STATUS status=OK; TM_TZ_CB *tm_tz_cb; struct timevect time_v; appname = argv[0]; if( TMtz_getopt(argc, argv, "n:name:f:file", &ioptind, ioptarg, &c) == OK) { switch (c) { case 'f': tz_file = ioptarg; break; case 'n': tz_name = ioptarg; break; default: break; } } else { TMtz_usage(); PCexit(FAIL); } if( tz_file == NULL) { if( tz_name == NULL) { /* Get II_TIMEZONE_NAME value */ NMgtAt(ERx("II_TIMEZONE_NAME"), &tz_def); if (!tz_def || !(*tz_def)) { SIprintf("%s: %s_TIMEZONE_NAME is not set\n", appname, SystemVarPrefix); PCexit(FAIL); } STncpy(tzname, tz_def, TM_MAX_TZNAME); tzname[ TM_MAX_TZNAME ] = EOS; } else { STncpy(tzname, tz_name, TM_MAX_TZNAME); tzname[ TM_MAX_TZNAME ] = EOS; } PMinit(); if( PMload( NULL, (PM_ERR_FUNC *)NULL) != OK) { SIprintf("%s: Error loading PM %s_CONFIG/config.dat file\n", appname, SystemVarPrefix); PCexit(FAIL); } /* Get timezone file name */ STprintf( tz_pmname, ERx("%s.*.tz.%s"), SystemCfgPrefix, tzname); if( PMget( tz_pmname, &pm_value) != OK) { SIprintf("%s: Error locating %s in PM config.dat file\n", appname, tz_pmname); PCexit(FAIL); } do { if((status = NMloc(FILES, PATH, ERx("zoneinfo"), &loc_root)) != OK) break; #if defined(conf_BUILD_ARCH_32_64) && defined(BUILD_ARCH64) if((status = LOfaddpath(&loc_root, ERx("lp64"), &loc_root)) != OK) break; #endif #if defined(conf_BUILD_ARCH_64_32) && defined(BUILD_ARCH32) { /* ** Reverse hybrid support must be available in ALL ** 32bit binaries */ char *rhbsup; NMgtAt("II_LP32_ENABLED", &rhbsup); if ( (rhbsup && *rhbsup) && ( !(STbcompare(rhbsup, 0, "ON", 0, TRUE)) || !(STbcompare(rhbsup, 0, "TRUE", 0, TRUE)))) status = LOfaddpath(&loc_root, "lp32", &loc_root); } #endif /* reverse hybrid */ STcopy( pm_value, tz_pmvalue); /* ** Compose the directory path */ for( p = tz_pmvalue, ip = tz_pmvalue; (p = STchr(ip, chr)) != NULL;) { *p = EOS; if((status = LOfaddpath(&loc_root, ip, &loc_root)) != OK) break; ip = CMnext(p); } /* ** Add file name to the directory path */ if((status = LOfroms(FILENAME, ip, &tmp_loc)) != OK) break; status = LOstfile( &tmp_loc, &loc_root); } while( FALSE); if( status != OK) { SIprintf("%s: Error composing timezone file name for %s\n", appname, tz_pmvalue); PCexit(FAIL); } } else { STcopy("<unknown>", tzname); STncpy( tzfile, tz_file, MAX_LOC); tzfile[ MAX_LOC ] = EOS; if( LOfroms(FILENAME&PATH, tzfile, &loc_root) != OK) { SIprintf("%s: Error composing timezone file name for %s\n", appname, tz_pmvalue); PCexit(FAIL); } } /* ** Now open the timezone information file */ do { if((status = SIfopen( &loc_root, ERx("r"), SI_VAR, sizeof buf, &fid)) != OK) break; status = SIread(fid, sizeof buf, &i, buf); status = SIclose(fid); } while(FALSE); if( status != OK) { LOtos( &loc_root, &out_file); SIprintf("%s: Error opening %s for timezone %s\n", appname, out_file, tzname); PCexit(FAIL); } tm_tz_cb = (TM_TZ_CB *)&buf; I4ASSIGN_MACRO( tm_tz_cb->timecnt, timecnt); /* Make sure the input file has correct file size */ if( timecnt > TM_MAX_TIMECNT || timecnt < 0 || i != sizeof(TM_TZ_CB) + timecnt*(sizeof(i4)+1)) { LOtos( &loc_root, &out_file); SIprintf( "%s: Invalid file format for timezone file %s for timezone %s\n", appname, out_file, tzname); SIprintf( " File size: %d, Expected file size: %d, time periods: %d\n", i, sizeof(TM_TZ_CB) + timecnt*(sizeof(i4)+1), timecnt); PCexit(FAIL); } /* Now we are all set to display the content of timezone information file */ LOtos( &loc_root, &out_file); SIprintf("\n\n"); SIprintf("timezone name: %s\n", tzname); SIprintf("timezone file: %s\n", out_file); SIprintf("-------------------------------------"); SIprintf("-------------------------------------\n"); if(timecnt == 0) { I4ASSIGN_MACRO( tm_tz_cb->tzinfo[0].gmtoff, tempi); SIprintf(" Fixed GMT offset (secs): %d\n", tempi); } else { SIprintf("\tPeriod Begin"); SIprintf("\t\tGMT offset\n"); SIprintf("\t(YYYY_MM_DD HH:MM)"); SIprintf("\t(Minute)\n\n"); tm_tztype = buf + sizeof(TM_TZ_CB); tm_tztime = tm_tztype + timecnt; i=0; while( i < timecnt) { I4ASSIGN_MACRO( *tm_tztime, tempi); /* Adjust for timezone */ if( i == 0) temptype = (i4)tm_tztype[i+1]; else temptype = (i4)tm_tztype[i-1]; I4ASSIGN_MACRO( tm_tz_cb->tzinfo[temptype].gmtoff, temptz); /* Get real timezone */ tempi += temptz; temptype = (i4)tm_tztype[i]; I4ASSIGN_MACRO( tm_tz_cb->tzinfo[temptype].gmtoff, temptz); TMtz_cvtime( tempi, &time_v); SIprintf("\t%04d_%02d_%02d %02d:%02d\t%d\t%s\n", time_v.tm_year+1900, time_v.tm_mon+1, time_v.tm_mday, time_v.tm_hour, time_v.tm_min, temptz/60, tm_tz_cb->tzlabel + tm_tz_cb->tzinfo[temptype].abbrind); tm_tztime += sizeof(i4); i++; } } PCexit(OK); }