⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
字号:
/* * Copyright (C) 1998, 1999, 2001, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <ctype.h>#include <string.h>#include <stdlib.h>#include <disk/DiskKey.hxx>#include <erosimg/App.hxx>#include <erosimg/Parse.hxx>#include <erosimg/ArchDescrip.hxx>#include <eros/StdKeyType.h>#define __EROS_PRIMARY_KEYDEF(name) { #name, (KT_##name >= FIRST_MISC_KEYTYPE) },/* OLD_MISCKEY(name) { #name, 0 }, */static const struct {  char *name;  int isValid;} KeyNames[KT_NUM_KEYTYPE] = {#include <eros/StdKeyType.h>};boolGetMiscKeyType(InternedString s, uint32_t& ty){  const char *sstr = s.str();    for (uint32_t i = 0; i < KT_NUM_KEYTYPE; i++) {    if (strcasecmp(sstr, KeyNames[i].name) == 0) {      if (KeyNames[i].isValid == 0)	return false;      ty = i;      return true;    }  }  return false;}void Parse::TrimLine(char *s){  for(; *s; s++) {    if (*s == '#' || *s == '\n')      *s = 0;  }    do {    *s = 0;    s--;  } while(isspace(*s));    s++;}boolParse::MatchKeyword(const char *&txt, const char* kwd){  const char* s = txt;    int len = strlen(kwd);  while(isspace(*s))    s++;  if (strncasecmp(s, kwd, len))    return false;  if (isalnum(s[len]))    return false;  s += len;  txt = s;    return true;}boolParse::Match(const char *&txt, const char* tok){  const char* s = txt;    int len = strlen(tok);  while(isspace(*s))    s++;  if (strncmp(s, tok, len))    return false;  s += len;  txt = s;    return true;}/* identifiers can be qualified with '.' in them.  We grab the whole * thing. */boolParse::MatchIdent(const char*&txt, InternedString& ident){  const char* s = txt;  while(isspace(*s))    s++;    if (isalpha(*s)) {    const char* id = s;    while (isalnum(*s) || *s == '.' || (*s == '_'))      s++;    ident = InternedString(id, s - id);    txt = s;    return true;  }  return false;  }boolParse::MatchArchitecture(const char*&txt, InternedString& arch){  const char* s = txt;  InternedString nm;  if (!MatchIdent(s, nm))    return false;  /* See if it's really an architecture name: */  if (RegDescrip::IsArchName(nm) == false)    return false;  arch = nm;  txt = s;  return true;}boolParse::MatchRegister(const char *&txt, InternedString& arch,		     RegDescrip*& rrd){  const char* s = txt;  RegDescrip *rd;    InternedString nm;  if (!MatchIdent(s, nm))    return false;  /* See if it's really an architecture name: */  if ( (rd = RegDescrip::Lookup(arch, nm)) ) {    txt = s;    rrd = rd;    return true;  }  return false;}/* Basically, match a hex number no longer than the required number of * bytes */boolParse::MatchRegValue(const char *&txt, RegDescrip* prd, InternedString& v){  const char *s = txt;  while(isspace(*s))    s++;  /* hopefully now looking at 0x... */  if (strncasecmp(s, "0x", 2))    return false;  s += 2;  /* now should be looking at the raw digits. */  /* count the hex digits: */  char digits[RegDescrip::MaxRegSize*2 + 3];/* "0x" + \0 */  digits[0] = '0';  digits[1] = 'x';  char *nextDigit = &digits[2];  uint32_t hexlen = prd->len * 2;	/* max hex digits to accept */    uint32_t len = 0;  while(isxdigit(*s) || *s == ' ') {    if (len >= hexlen)      return false;    if (isxdigit(*s))      *nextDigit++ = *s;        s++;  }  *nextDigit = 0;  InternedString iDigits(digits);  v = iDigits;    txt = s;    return true;}boolParse::MatchFileName(const char*&txt, InternedString& fileName){  const char* s = txt;  while(isspace(*s))    s++;    if (*s == 0) {    fileName = 0;    return false;  }    /* now looking at a character that is not a space - assume   * that it is the start of a file name.   */  const char* name = s;    while (*s && !isspace(*s))    s++;  fileName = InternedString(name, s - name);  txt = s;  return true;  }boolParse::MatchEOL(const char *&txt){  const char *s = txt;  while(isspace(*s))    s++;    if (*s)    return false;  txt = s;  return true;}/* parse the arguments for the 'page' or 'node' division type: */boolParse::MatchWord(const char *&txt, uint32_t& w){  const char *s = txt;  while(isspace(*s))    s++;    if (isdigit(*s)) {    char *next;    w = strtoul(s, &next, 0);    if (s != next) {      s = next;      txt = s;      return true;    }  }  return false;}boolParse::MatchKeyData(const char *&txt, uint32_t& w){  uint32_t w2;  const char *s = txt;  MatchWord(s, w2);  if (w2 > EROS_KEYDATA_MAX)    return false;  w = w2;  txt = s;  return true;}boolParse::MatchSlot(const char *&txt, uint32_t& slot){  const char *s = txt;  MatchWord(s, slot);  if (slot >= EROS_NODE_SIZE)    return false;  txt = s;  return true;}boolParse::MatchOID(const char *&txt, OID& oid){  const char *s = txt;  while(isspace(*s))    s++;  if (strncasecmp(s, "oid", 3))    return false;  s += 3;  while(isspace(*s))    s++;  if (*s != '=')    return false;  s++;  if (!MatchOIDVal(s, oid))    return false;  txt = s;  return true;}boolParse::MatchLID(const char *&txt, OID& oid){  const char *s = txt;  while(isspace(*s))    s++;  if (strncasecmp(s, "lid", 3) && strncasecmp(s, "oid", 3))    return false;  if (strncasecmp(s, "lid", 3))    Diag::warning("use of 'oid' in cklog line is obsolete!\n");  s += 3;  while(isspace(*s))    s++;  if (*s != '=')    return false;  s++;  if (!MatchOIDVal(s, oid))    return false;  txt = s;  return true;}boolParse::MatchOIDVal(const char *&txt, OID& oid){  const char *s = txt;  while(isspace(*s))    s++;  /* hopefully now looking at 0x... */  if (strncasecmp(s, "0x", 2))    return false;  s += 2;  /* now should be looking at the raw digits. */  /* count the hex digits: */  const char *xstr = s;  while(isxdigit(*s))    s++;  int len = s - xstr;  if (len > 16 || len == 0)    return false;    char digits[17];		/* 16 hex digits plus zero */  strncpy(digits, xstr, len);  digits[len] = 0;      uint32_t hi = 0;  uint32_t lo = 0;  if (len > 8) {    lo = strtoul(&digits[len-8], 0, 16);    digits[len-8] = 0;    hi = strtoul(digits, 0, 16);  }  else {    lo = strtoul(digits, 0, 16);  }  oid = hi;  oid <<= 32;  oid |= lo;  txt = s;    return true;}boolParse::MatchNumKeyVal(const char *&txt, uint32_t& hi,		      uint32_t& mid, uint32_t& lo){  const char *s = txt;  while(isspace(*s))    s++;  /* hopefully now looking at 0x... */  if (strncasecmp(s, "0x", 2))    return false;  s += 2;  /* now should be looking at the raw digits. */  /* count the hex digits: */  char digits[25];  uint32_t len = 0;  while(isxdigit(*s) || *s == ' ') {    if (len > 24)      return false;    if (isxdigit(*s))      digits[len++] = *s;        s++;  }  if (len == 0)    return false;    digits[len] = 0;      hi = 0;  mid = 0;  if (len < 8) {    lo = strtoul(digits, 0, 16);  }  else if (len < 16) {    lo = strtoul(&digits[len-8], 0, 16);    digits[len-8] = 0;    mid = strtoul(digits, 0, 16);  }  else {    lo = strtoul(&digits[len-8], 0, 16);    digits[len-8] = 0;    mid = strtoul(&digits[len-16], 0, 16);    digits[len-16] = 0;    hi = strtoul(digits, 0, 16);  }  txt = s;    return true;}boolParse::MatchKey(const char *&txt, DiskKey& key){  const char *s = txt;  while(isspace(*s))    s++;  KeyType kt;    /* looking for a string that is a plausible key type: */  if (strncasecmp(s, "start", 5) == 0) {    s += 5;    kt = KT_Start;  }  else if (strncasecmp(s, "number", 6) == 0) {    s += 6;    kt = KT_Number;  }  else if (strncasecmp(s, "range", 5) == 0) {    s += 5;    kt = KT_Range;  }  else if (strncasecmp(s, "page", 4) == 0) {    s += 4;    kt = KT_Page;  }  else if (strncasecmp(s, "node", 4) == 0) {    s += 4;    kt = KT_Node;  }  else if (strncasecmp(s, "segment", 7) == 0) {    s += 7;    kt = KT_Segment;  }  else if (strncasecmp(s, "sched", 5) == 0) {    s += 5;    kt = KT_Sched;  }  else if (strncasecmp(s, "misc", 4) == 0) {    s += 4;    kt = FIRST_MISC_KEYTYPE;  }  else {    return false;  }  while(isspace(*s))    s++;  if (!Match(s, "("))    return false;  switch (kt) {  case KT_Start:    {      uint32_t w;      OID oid;      if ( MatchOID(s, oid) &&		Match(s, ",") &&		MatchWord(s, w) &&		(w <= EROS_KEYDATA_MAX) &&		Match(s, ")") ) {	key = StartKey(oid, w);	txt = s;	return true;      }      break;    }  case KT_Number:    {      uint32_t hi, mid, lo;            if (MatchNumKeyVal(s, hi, mid, lo) &&	  Match(s, ")") ) {	key = NumberKey(lo, mid, hi);	txt = s;	return true;      }      break;    }  case KT_Range:    {      OID oidlo, oidhi;      if (MatchOIDVal(s, oidlo) &&	  Match(s, ":") &&	  MatchOIDVal(s, oidhi) &&	  Match(s, ")") ) {	key = RangeKey(oidlo, oidhi);	txt = s;	return true;      }      break;    }  case KT_Page:  case KT_Node:  case KT_Segment:    {      OID oid;      uint32_t blss = 0;      if (kt == KT_Page)	blss = EROS_PAGE_BLSS;      /* Node/Seg keys have lots of attributes, so the following is       * a bit tricky.  First, parse the '(oid' part:       */            bool expectComma = false;      bool readOnly = false;      bool noCall = false;      bool rh = false;            /* Now try to parse the various attributes: */      while (!Match(s, ")")) {	if (expectComma && Match(s, ",") == false)	  return false;	expectComma = true;	const char *ssave = s;	if ( MatchStart(s, ssave) &&	     MatchKeyword(s, "oid") &&	     Match(s, "=") &&	     MatchOIDVal(s, oid) )	  continue;	if ( MatchStart(s, ssave) &&	     MatchKeyword(s, "ro") ) {	  readOnly = true;	  continue;	}	if ( MatchStart(s, ssave) &&	     MatchKeyword(s, "nocall") ) {	  noCall = true;	  continue;	}	if ( MatchStart(s, ssave) &&	     MatchKeyword(s, "rh") ) {	  rh = true;	  continue;	}	/* accept this just for my sanity: */	if ( kt != KT_Page &&	     MatchStart(s, ssave) &&	     MatchKeyword(s, "lss") &&	     Match(s, "=") &&	     MatchWord(s, blss) )	  continue;	if ( kt != KT_Page &&	     MatchStart(s, ssave) &&	     MatchKeyword(s, "blss") &&	     Match(s, "=") &&	     MatchWord(s, blss) )	  continue;	return false;      }      switch(kt) {      case KT_Segment:	key = SegmentKey(oid, blss, readOnly, noCall);	break;      case KT_Page:	key = DataPageKey(oid, readOnly);	break;      case KT_Node:	key = NodeKey(oid, readOnly);	break;      default:	break;      }            if (blss)	key.SetBlss(blss);      if (readOnly)	key.SetReadOnly();      if (noCall)	key.SetNoCall();      if (rh)	key.SetRdHazard();      txt = s;      return true;      break;    }  case KT_Sched:    {      uint32_t prio;            if (MatchWord(s, prio) &&	  Match(s, ")") ) {	key = SchedKey(prio);	txt = s;	return true;      }      break;    }    break;  case FIRST_MISC_KEYTYPE:    {      InternedString name;            if (MatchIdent(s, name) &&	  Match(s, ")") ) {	uint32_t miscType;		if (GetMiscKeyType(name, miscType) == false)	  return false;	key = MiscKey(miscType);	txt = s;	return true;      }      break;    }    break;  default:    /* Don't know how to parse the others. */    return false;  }  return false;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -