예제 #1
0
/** Startup tray buttons. */
void StartupTrayButtons() {

   TrayButtonType *bp;

   for(bp = buttons; bp; bp = bp->next) {
      if(bp->label) {
         bp->cp->requestedWidth
            = GetStringWidth(FONT_TRAYBUTTON, bp->label) + 4;
         bp->cp->requestedHeight
            = GetStringHeight(FONT_TRAYBUTTON);
      } else {
         bp->cp->requestedWidth = 0;
         bp->cp->requestedHeight = 0;
      }
      if(bp->iconName) {
         bp->icon = LoadNamedIcon(bp->iconName);
         if(JLIKELY(bp->icon)) {
            bp->cp->requestedWidth += bp->icon->image->width;
            bp->cp->requestedHeight += bp->icon->image->height;
         } else {
            Warning(_("could not load tray icon: \"%s\""), bp->iconName);
         }
      }
      bp->cp->requestedWidth += 2 * BUTTON_SIZE;
      bp->cp->requestedHeight += 2 * BUTTON_SIZE;
   }

}
예제 #2
0
파일: hint.c 프로젝트: LEONID-DOROGIN/PCSI
/** Read the WM state for a window. */
void ReadWMState(Window win, ClientState *state)
{

   Status status;
   unsigned long count;
   unsigned long extra;
   Atom realType;
   int realFormat;
   unsigned long *temp;

   status = JXGetWindowProperty(display, win, atoms[ATOM_WM_STATE], 0, 2,
                                False, atoms[ATOM_WM_STATE],
                                &realType, &realFormat,
                                &count, &extra, (unsigned char**)&temp);
   if(JLIKELY(status == Success && realFormat == 32 && count == 2)) {
      switch(temp[0]) {
      case IconicState:
         state->status |= STAT_MINIMIZED;
         break;
      case WithdrawnState:
         state->status &= ~STAT_MAPPED;
         break;
      default:
         break;
      }
      JXFree(temp);
   }

}
예제 #3
0
파일: parse.c 프로젝트: technosaurus/jwm
/** Parse move mode. */
void ParseMoveMode(const TokenNode *tp) {

   const char *str;

   str = FindAttribute(tp->attributes, COORDINATES_ATTRIBUTE);
   if(str) {
      settings.moveStatusType = ParseStatusWindowType(tp, str);
   }

   str = FindAttribute(tp->attributes, DELAY_ATTRIBUTE);
   if(str) {
      settings.desktopDelay = ParseUnsigned(tp, str);
   }

   if(JLIKELY(tp->value)) {
      if(!strcmp(tp->value, OUTLINE_VALUE)) {
         settings.moveMode = MOVE_OUTLINE;
      } else if(!strcmp(tp->value, OPAQUE_VALUE)) {
         settings.moveMode = MOVE_OPAQUE;
      } else {
         ParseError(tp, "invalid move mode: %s", tp->value);
      }
   } else {
      ParseError(tp, "move mode not specified");
   }

}
예제 #4
0
파일: parse.c 프로젝트: Nehamkin/jwm
/** Parse a clock tray component. */
void ParseClock(const TokenNode *tp, TrayType *tray)
{
   TrayComponentType *cp;
   const char *format;
   const char *zone;
   const char *temp;
   int width, height;

   Assert(tp);
   Assert(tray);

   format = FindAttribute(tp->attributes, "format");
   zone = FindAttribute(tp->attributes, "zone");

   temp = FindAttribute(tp->attributes, WIDTH_ATTRIBUTE);
   if(temp) {
      width = ParseUnsigned(tp, temp);
   } else {
      width = 0;
   }

   temp = FindAttribute(tp->attributes, HEIGHT_ATTRIBUTE);
   if(temp) {
      height = ParseUnsigned(tp, temp);
   } else {
      height = 0;
   }

   cp = CreateClock(format, zone, width, height);
   if(JLIKELY(cp)) {
      ParseTrayComponentActions(tp, cp, AddClockAction);
      AddTrayComponent(tray, cp);
   }

}
예제 #5
0
파일: parse.c 프로젝트: technosaurus/jwm
/** Parse a spacer tray component. */
void ParseSpacer(const TokenNode *tp, TrayType *tray) {

   TrayComponentType *cp;
   int width;
   int height;
   char *str;

   Assert(tp);
   Assert(tray);

   /* Get the width. */
   str = FindAttribute(tp->attributes, WIDTH_ATTRIBUTE);
   if(str) {
      width = ParseUnsigned(tp, str);
   } else {
      width = 0;
   }

   /* Get the height. */
   str = FindAttribute(tp->attributes, HEIGHT_ATTRIBUTE);
   if(str) {
      height = ParseUnsigned(tp, str);
   } else {
      height = 0;
   }

   /* Create the spacer. */
   cp = CreateSpacer(width, height);
   if(JLIKELY(cp)) {
      AddTrayComponent(tray, cp);
   }

}
예제 #6
0
파일: traybutton.c 프로젝트: kuailexs/jwm
/** Startup tray buttons. */
void StartupTrayButtons(void)
{
   TrayButtonType *bp;
   for(bp = buttons; bp; bp = bp->next) {
      if(bp->label) {
         bp->cp->requestedWidth
            = GetStringWidth(FONT_TRAY, bp->label) + 4;
         bp->cp->requestedHeight = GetStringHeight(FONT_TRAY);
      } else {
         bp->cp->requestedWidth = 0;
         bp->cp->requestedHeight = 0;
      }
      if(bp->iconName) {
         bp->icon = LoadNamedIcon(bp->iconName, 1, 1);
         if(JLIKELY(bp->icon)) {
            bp->cp->requestedWidth += bp->icon->images->width + 4;
            if(bp->label) {
               bp->cp->requestedWidth -= 2;
            }
            bp->cp->requestedHeight
               = Max(bp->icon->images->height + 4, bp->cp->requestedHeight);
         } else {
            Warning(_("could not load tray icon: \"%s\""), bp->iconName);
         }
      }
   }
}
예제 #7
0
파일: group.c 프로젝트: harryhaaren/jwm
/** Add a window class to a group. */
void AddGroupClass(GroupType *gp, const char *pattern)
{
   Assert(gp);
   if(JLIKELY(pattern)) {
      AddPattern(&gp->patterns, pattern, MATCH_CLASS);
   } else {
      Warning(_("invalid group class"));
   }
}
예제 #8
0
파일: group.c 프로젝트: harryhaaren/jwm
/** Add a window name to a group. */
void AddGroupName(GroupType *gp, const char *pattern)
{
   Assert(gp);
   if(JLIKELY(pattern)) {
      AddPattern(&gp->patterns, pattern, MATCH_NAME);
   } else {
      Warning(_("invalid group name"));
   }
}
예제 #9
0
파일: parse.c 프로젝트: kuailexs/jwm
/** Parse popup style. */
void ParsePopupStyle(const TokenNode *tp)
{
   static const StringMappingType enable_mapping[] = {
      { "button", POPUP_BUTTON   },
      { "clock",  POPUP_CLOCK    },
      { "false",  POPUP_NONE     },
      { "pager",  POPUP_PAGER    },
      { "task",   POPUP_TASK     },
      { "true",   POPUP_ALL      }
   };
   const TokenNode *np;
   const char *str;
   char *tok;

   tok = FindAttribute(tp->attributes, "enabled");
   if(tok) {
      settings.popupMask = POPUP_NONE;
      tok = strtok(tok, ",");
      while(tok) {
         const int x = FindValue(enable_mapping,
                                 ARRAY_LENGTH(enable_mapping), tok);
         if(JLIKELY(x >= 0)) {
            settings.popupMask |= x;
         } else {
            ParseError(tp, "invalid value for 'enabled': \"%s\"", tok);
         }
         tok = strtok(NULL, ",");
      }
   }

   str = FindAttribute(tp->attributes, "delay");
   if(str) {
      settings.popupDelay = ParseUnsigned(tp, str);
   }

   for(np = tp->subnodeHead; np; np = np->next) {
      switch(np->type) {
      case TOK_FONT:
         SetFont(FONT_POPUP, np->value);
         break;
      case TOK_FOREGROUND:
         SetColor(COLOR_POPUP_FG, np->value);
         break;
      case TOK_BACKGROUND:
         SetColor(COLOR_POPUP_BG, np->value);
         break;
      case TOK_OUTLINE:
         SetColor(COLOR_POPUP_OUTLINE, np->value);
         break;
      default:
         InvalidTag(np, TOK_POPUPSTYLE);
         break;
      }
   }

}
예제 #10
0
파일: place.c 프로젝트: KarlGodt/jwm
/** Insert a bounding box to the list of struts. */
void InsertStrut(const BoundingBox *box, ClientNode *np)
{
   if(JLIKELY(box->width > 0 && box->height > 0)) {
      Strut *sp = Allocate(sizeof(Strut));
      sp->client = np;
      sp->box = *box;
      sp->next = struts;
      struts = sp;
   }
}
예제 #11
0
파일: parse.c 프로젝트: Nehamkin/jwm
/** Parse a menu include. */
MenuItem *ParseMenuInclude(const TokenNode *tp, Menu *menu,
                           MenuItem *last)
{
   TokenNode *start = ParseMenuIncludeHelper(tp, tp->value);
   if(JLIKELY(start)) {
      last = ParseMenuItem(start->subnodeHead, menu, last);
      ReleaseTokens(start);
   }
   return last;
}
예제 #12
0
파일: parse.c 프로젝트: Nehamkin/jwm
/** Parse a dynamic menu (called from menu code). */
Menu *ParseDynamicMenu(const char *command)
{
   Menu *menu = NULL;
   TokenNode *start = ParseMenuIncludeHelper(NULL, command);
   if(JLIKELY(start)) {
      menu = ParseMenu(start);
      ReleaseTokens(start);
   }
   return menu;
}
예제 #13
0
파일: parse.c 프로젝트: technosaurus/jwm
/** Parse focus model. */
void ParseFocusModel(const TokenNode *tp) {
   if(JLIKELY(tp->value)) {
      if(!strcmp(tp->value, "sloppy")) {
         settings.focusModel = FOCUS_SLOPPY;
      } else if(!strcmp(tp->value, "click")) {
         settings.focusModel = FOCUS_CLICK;
      } else {
         ParseError(tp, "invalid focus model: \"%s\"", tp->value);
      }
   } else {
      ParseError(tp, "focus model not specified");
   }
}
예제 #14
0
파일: cursor.c 프로젝트: technosaurus/jwm
/** Grab the mouse for choosing a window. */
char GrabMouseForChoose()
{
   int result;
   unsigned int mask;
   mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
   result = JXGrabPointer(display, rootWindow, False, mask,
                          GrabModeAsync, GrabModeAsync, None,
                          cursors[CURSOR_CHOOSE], CurrentTime);
   if(JLIKELY(result == GrabSuccess)) {
      mousew = rootWindow;
      return 1;
   } else {
      return 0;
   }
}
예제 #15
0
파일: cursor.c 프로젝트: bbidulock/jwmtools
/** Grab the mouse for choosing a window. */
int GrabMouseForChoose() {

   int result;

   result = JXGrabPointer(display, rootWindow, False,
      ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
      GrabModeAsync, GrabModeAsync, None, chooseCursor, CurrentTime);

   if(JLIKELY(result == GrabSuccess)) {
      return 1;
   } else {
      return 0;
   }

}
예제 #16
0
파일: parse.c 프로젝트: Nehamkin/jwm
/** Parse layer. */
WinLayerType ParseLayer(const TokenNode *tp, const char *str)
{
   static const StringMappingType mapping[] = {
      { "above",  LAYER_ABOVE    },
      { "below",  LAYER_BELOW    },
      { "normal", LAYER_NORMAL   }
   };
   const int x = FindValue(mapping, ARRAY_LENGTH(mapping), str);
   if(JLIKELY(x >= 0)) {
      return x;
   }  else {
      ParseError(tp, "invalid layer: %s", str);
      return LAYER_NORMAL;
   }
}
예제 #17
0
파일: parse.c 프로젝트: Nehamkin/jwm
/** Parse a string using a string mapping. */
int ParseAttribute(const StringMappingType *mapping, int count,
                   const TokenNode *tp, const char *attr, int def)
{
   const char *str = FindAttribute(tp->attributes, attr);
   if(str == NULL) {
      return def;
   } else {
      const int x = FindValue(mapping, count, str);
      if(JLIKELY(x >= 0)) {
         return x;
      } else {
         ParseError(tp, "invalid value for %s: \"%s\"", attr, str);
         return def;
      }
   }
}
예제 #18
0
파일: parse.c 프로젝트: Nehamkin/jwm
/** Parse a token value using a string mapping. */
int ParseTokenValue(const StringMappingType *mapping, int count,
                    const TokenNode *tp, int def)
{
   if(JUNLIKELY(tp->value == NULL)) {
      ParseError(tp, "%s is empty", GetTokenName(tp));
      return def;
   } else {
      const int x = FindValue(mapping, count, tp->value);
      if(JLIKELY(x >= 0)) {
         return x;
      } else {
         ParseError(tp, "invalid %s: \"%s\"", GetTokenName(tp), tp->value);
         return def;
      }
   }
}
예제 #19
0
파일: cursor.c 프로젝트: bbidulock/jwmtools
/** Grab the mouse for resizing a window. */
int GrabMouseForResize(BorderActionType action) {

   Cursor cur;
   int result;

   cur = GetFrameCursor(action);

   result = JXGrabPointer(display, rootWindow, False, ButtonPressMask
      | ButtonReleaseMask | PointerMotionMask, GrabModeAsync,
      GrabModeAsync, None, cur, CurrentTime);

   if(JLIKELY(result == GrabSuccess)) {
      return 1;
   } else {
      return 0;
   }

}
예제 #20
0
파일: parse.c 프로젝트: technosaurus/jwm
/** Parse a button tray component. */
void ParseTrayButton(const TokenNode *tp, TrayType *tray) {

   TrayComponentType *cp;
   const char *icon;
   const char *label;
   const char *popup;
   const char *temp;
   unsigned int width, height;
   char border;

   Assert(tp);
   Assert(tray);

   icon = FindAttribute(tp->attributes, ICON_ATTRIBUTE);
   label = FindAttribute(tp->attributes, LABEL_ATTRIBUTE);
   popup = FindAttribute(tp->attributes, POPUP_ATTRIBUTE);

   temp = FindAttribute(tp->attributes, BORDER_ATTRIBUTE);
   if(temp && !strcmp(temp, FALSE_VALUE)) {
      border = 0;
   } else {
      border = 1;
   }

   temp = FindAttribute(tp->attributes, WIDTH_ATTRIBUTE);
   if(temp) {
      width = ParseUnsigned(tp, temp);
   } else {
      width = 0;
   }

   temp = FindAttribute(tp->attributes, HEIGHT_ATTRIBUTE);
   if(temp) {
      height = ParseUnsigned(tp, temp);
   } else {
      height = 0;
   }

   cp = CreateTrayButton(icon, label, tp->value, popup, width, height, border);
   if(JLIKELY(cp)) {
      AddTrayComponent(tray, cp);
   }

}
예제 #21
0
파일: parse.c 프로젝트: technosaurus/jwm
/** Parse a clock tray component. */
void ParseClock(const TokenNode *tp, TrayType *tray) {

   TrayComponentType *cp;
   const char *format;
   const char *zone;
   const char *command;
   const char *temp;
   int width, height;

   Assert(tp);
   Assert(tray);

   format = FindAttribute(tp->attributes, FORMAT_ATTRIBUTE);

   zone = FindAttribute(tp->attributes, ZONE_ATTRIBUTE);

   if(tp->value && strlen(tp->value) > 0) {
      command = tp->value;
   } else {
      command = NULL;
   }

   temp = FindAttribute(tp->attributes, WIDTH_ATTRIBUTE);
   if(temp) {
      width = ParseUnsigned(tp, temp);
   } else {
      width = 0;
   }

   temp = FindAttribute(tp->attributes, HEIGHT_ATTRIBUTE);
   if(temp) {
      height = ParseUnsigned(tp, temp);
   } else {
      height = 0;
   }

   cp = CreateClock(format, zone, command, width, height);
   if(JLIKELY(cp)) {
      AddTrayComponent(tray, cp);
   }

}
예제 #22
0
파일: key.c 프로젝트: kuailexs/jwm
/** Show a root menu caused by a key binding. */
void ShowKeyMenu(const XKeyEvent *event)
{

    KeyNode *np;
    unsigned int state;

    /* Remove the lock key modifiers. */
    state = event->state & ~lockMask;

    for(np = bindings; np; np = np->next) {
        if(np->state == state && np->code == event->keycode) {
            const int button = GetRootMenuIndexFromString(np->command);
            if(JLIKELY(button >= 0)) {
                ShowRootMenu(button, -1, -1, 1);
            }
            return;
        }
    }

}
예제 #23
0
파일: tray.c 프로젝트: Nehamkin/jwm
/** Set the vertical tray alignment. */
void SetTrayVerticalAlignment(TrayType *tp, const char *str)
{
   static const StringMappingType mapping[] = {
      { "bottom",    TALIGN_BOTTOM  },
      { "center",    TALIGN_CENTER  },
      { "fixed",     TALIGN_FIXED   },
      { "top",       TALIGN_TOP     }
   };

   if(!str) {
      tp->valign = TALIGN_FIXED;
   } else {
      const int x = FindValue(mapping, ARRAY_LENGTH(mapping), str);
      if(JLIKELY(x >= 0)) {
         tp->valign = x;
      } else {
         Warning(_("invalid tray vertical alignment: \"%s\""), str);
         tp->valign = TALIGN_FIXED;
      }
   }
}
예제 #24
0
파일: tray.c 프로젝트: Nehamkin/jwm
/** Set the horizontal tray alignment. */
void SetTrayHorizontalAlignment(TrayType *tp, const char *str)
{
   static const StringMappingType mapping[] = {
      { "center",    TALIGN_CENTER  },
      { "fixed",     TALIGN_FIXED   },
      { "left",      TALIGN_LEFT    },
      { "right",     TALIGN_RIGHT   }
   };

   if(!str) {
      tp->halign = TALIGN_FIXED;
   } else {
      const int x = FindValue(mapping, ARRAY_LENGTH(mapping), str);
      if(JLIKELY(x >= 0)) {
         tp->halign = x;
      } else {
         Warning(_("invalid tray horizontal alignment: \"%s\""), str);
         tp->halign = TALIGN_FIXED;
      }
   }
}
예제 #25
0
파일: parse.c 프로젝트: technosaurus/jwm
/** Parse resize mode. */
void ParseResizeMode(const TokenNode *tp) {

   const char *str;

   str = FindAttribute(tp->attributes, COORDINATES_ATTRIBUTE);
   if(str) {
      settings.resizeStatusType = ParseStatusWindowType(tp, str);
   }

   if(JLIKELY(tp->value)) {
      if(!strcmp(tp->value, OUTLINE_VALUE)) {
         settings.resizeMode = RESIZE_OUTLINE;
      } else if(!strcmp(tp->value, OPAQUE_VALUE)) {
         settings.resizeMode = RESIZE_OPAQUE;
      } else {
         ParseError(tp, "invalid resize mode: %s", tp->value);
      }
   } else {
      ParseError(tp, "resize mode not specified");
   }

}
예제 #26
0
파일: parse.c 프로젝트: Nehamkin/jwm
/** Parse a dock tray component. */
void ParseDock(const TokenNode *tp, TrayType *tray) {

   TrayComponentType *cp;
   int width;
   char *str;

   Assert(tp);
   Assert(tray);

   str = FindAttribute(tp->attributes, WIDTH_ATTRIBUTE);
   if(str) {
      width = ParseUnsigned(tp, str);
   } else {
      width = 0;
   }

   cp = CreateDock(width);
   if(JLIKELY(cp)) {
      AddTrayComponent(tray, cp);
   }

}
예제 #27
0
파일: parse.c 프로젝트: Nehamkin/jwm
/** Parse a button tray component. */
void ParseTrayButton(const TokenNode *tp, TrayType *tray)
{

   TrayComponentType *cp;
   const char *icon;
   const char *label;
   const char *popup;
   const char *temp;
   unsigned int width, height;

   Assert(tp);
   Assert(tray);

   icon = FindAttribute(tp->attributes, ICON_ATTRIBUTE);
   label = FindAttribute(tp->attributes, LABEL_ATTRIBUTE);
   popup = FindAttribute(tp->attributes, "popup");

   temp = FindAttribute(tp->attributes, WIDTH_ATTRIBUTE);
   if(temp) {
      width = ParseUnsigned(tp, temp);
   } else {
      width = 0;
   }

   temp = FindAttribute(tp->attributes, HEIGHT_ATTRIBUTE);
   if(temp) {
      height = ParseUnsigned(tp, temp);
   } else {
      height = 0;
   }

   cp = CreateTrayButton(icon, label, popup, width, height);
   if(JLIKELY(cp)) {
      AddTrayComponent(tray, cp);
      ParseTrayComponentActions(tp, cp, AddTrayButtonAction);
   }

}
예제 #28
0
파일: parse.c 프로젝트: technosaurus/jwm
/** Parse snap mode for moving windows. */
void ParseSnapMode(const TokenNode *tp) {

   const char *distance;

   distance = FindAttribute(tp->attributes, DISTANCE_ATTRIBUTE);
   if(distance) {
      settings.snapDistance = ParseUnsigned(tp, distance);
   }

   if(JLIKELY(tp->value)) {
      if(!strcmp(tp->value, "none")) {
         settings.snapMode = SNAP_NONE;
      } else if(!strcmp(tp->value, "screen")) {
         settings.snapMode = SNAP_SCREEN;
      } else if(!strcmp(tp->value, "border")) {
         settings.snapMode = SNAP_BORDER;
      } else {
         ParseError(tp, "invalid snap mode: %s", tp->value);
      }
   } else {
      ParseError(tp, "snap mode not specified");
   }
}
예제 #29
0
파일: group.c 프로젝트: harryhaaren/jwm
/** Apply a group to a client. */
void ApplyGroup(const GroupType *gp, ClientNode *np)
{

   OptionListType *lp;

   Assert(gp);
   Assert(np);
   for(lp = gp->options; lp; lp = lp->next) {
      switch(lp->option) {
      case OPTION_STICKY:
         np->state.status |= STAT_STICKY;
         break;
      case OPTION_NOLIST:
         np->state.status |= STAT_NOLIST;
         break;
      case OPTION_NOPAGER:
         np->state.status |= STAT_NOPAGER;
         break;
      case OPTION_BORDER:
         np->state.border |= BORDER_OUTLINE;
         break;
      case OPTION_NOBORDER:
         np->state.border &= ~BORDER_OUTLINE;
         break;
      case OPTION_TITLE:
         np->state.border |= BORDER_TITLE;
         break;
      case OPTION_NOTITLE:
         np->state.border &= ~BORDER_TITLE;
         np->state.border &= ~BORDER_SHADE;
         break;
      case OPTION_LAYER:
         np->state.layer = lp->uvalue;
         break;
      case OPTION_DESKTOP:
         if(JLIKELY(lp->uvalue >= 1 && lp->uvalue <= settings.desktopCount)) {
            np->state.desktop = lp->uvalue - 1;
         } else {
            Warning(_("invalid group desktop: %d"), lp->uvalue);
         }
         break;
      case OPTION_ICON:
         DestroyIcon(np->icon);
         np->icon = LoadNamedIcon(lp->svalue, 1);
         break;
      case OPTION_PIGNORE:
         np->state.status |= STAT_PIGNORE;
         break;
      case OPTION_IIGNORE:
         np->state.status |= STAT_IIGNORE;
         break;
      case OPTION_MAXIMIZED:
         np->state.status |= STAT_HMAX | STAT_VMAX;
         break;
      case OPTION_MINIMIZED:
         np->state.status |= STAT_MINIMIZED;
         break;
      case OPTION_SHADED:
         np->state.status |= STAT_SHADED;
         break;
      case OPTION_OPACITY:
         np->state.opacity = lp->uvalue;
         np->state.status |= STAT_OPACITY;
         break;
      case OPTION_MAX_V:
         np->state.border &= ~BORDER_MAX_H;
         break;
      case OPTION_MAX_H:
         np->state.border &= ~BORDER_MAX_V;
         break;
      case OPTION_NOFOCUS:
         np->state.status |= STAT_NOFOCUS;
         break;
      case OPTION_NOSHADE:
         np->state.border &= ~BORDER_SHADE;
         break;
      case OPTION_CENTERED:
         np->state.status |= STAT_CENTERED;
         break;
      case OPTION_TILED:
         np->state.status |= STAT_TILED;
         break;
      case OPTION_NOTURGENT:
         np->state.status |= STAT_NOTURGENT;
         break;
      case OPTION_CONSTRAIN:
         np->state.border |= BORDER_CONSTRAIN;
         break;
      default:
         Debug("invalid option: %d", lp->option);
         break;
      }
   }

}
예제 #30
0
파일: lex.c 프로젝트: KarlGodt/jwm
/** Tokenize data. */
TokenNode *Tokenize(const char *line, const char *fileName)
{
   AttributeNode *ap;
   TokenNode *current;
   char *temp;
   unsigned int x;
   unsigned int offset;
   unsigned int lineNumber;
   char inElement;
   char found;

   head = NULL;
   current = NULL;
   inElement = 0;
   lineNumber = 1;

   x = 0;
   /* Skip any initial white space. */
   while(IsSpace(line[x], &lineNumber)) {
      x += 1;
   }

   /* Skip any XML stuff. */
   if(!strncmp(line + x, "<?", 2)) {
      while(line[x]) {
         if(line[x] == '\n') {
            lineNumber += 1;
         }
         if(!strncmp(line + x, "?>", 2)) {
            x += 2;
            break;
         }
         x += 1;
      }
   }

   /* Process the XML data. */
   while(line[x]) {

      /* Skip comments and white space. */
      do {

         /* Skip white space. */
         while(IsSpace(line[x], &lineNumber)) {
            x += 1;
         }

         /* Skip comments */
         found = 0;
         if(!strncmp(line + x, "<!--", 4)) {
            while(line[x]) {
               if(line[x] == '\n') {
                  lineNumber += 1;
               }
               if(!strncmp(line + x, "-->", 3)) {
                  x += 3;
                  found = 1;
                  break;
               }
               x += 1;
            }
         }

      } while(found);

      switch(line[x]) {
      case '<':
         x += 1;
         if(line[x] == '/') {

            /* Close tag. */
            x += 1;
            temp = ReadElementName(line + x);
            if(current) {
               if(JLIKELY(temp)) {
                  if(JUNLIKELY(current->type != LookupType(temp, NULL))) {
                     Warning(_("%s[%u]: close tag \"%s\" does not "
                             "match open tag \"%s\""),
                             fileName, lineNumber, temp,
                             GetTokenName(current));
                  }
               } else {
                  Warning(_("%s[%u]: unexpected and invalid close tag"),
                          fileName, lineNumber);
               }
               current = current->parent;
            } else {
               if(temp) {
                  Warning(_("%s[%u]: close tag \"%s\" without open tag"),
                          fileName, lineNumber, temp);
               } else {
                  Warning(_("%s[%u]: invalid close tag"), fileName, lineNumber);
               }
            }
            if(temp) {
               x += strlen(temp);
               Release(temp);
            }

         } else {

            /* Open tag. */
            current = CreateNode(current, fileName, lineNumber);
            temp = ReadElementName(line + x);
            if(JLIKELY(temp)) {
               x += strlen(temp);
               LookupType(temp, current);
               Release(temp);
            } else {
               Warning(_("%s[%u]: invalid open tag"), fileName, lineNumber);
            }

         }
         inElement = 1;
         break;
      case '/':

         /* End of open/close tag. */
         if(inElement) {
            x += 1;
            if(JLIKELY(line[x] == '>' && current)) {
               x += 1;
               current = current->parent;
               inElement = 0;
            } else {
               Warning(_("%s[%u]: invalid tag"), fileName, lineNumber);
            }
         } else {
            goto ReadDefault;
         }

         break;
      case '>':

         /* End of open tag. */
         x += 1;
         inElement = 0;
         break;

      default:
ReadDefault:
         if(inElement) {

            /* In the open tag; read attributes. */
            ap = CreateAttribute(current);
            ap->name = ReadElementName(line + x);
            if(ap->name) {
               x += strlen(ap->name);
               if(line[x] == '=') {
                  x += 1;
               }
               if(line[x] == '\"') {
                  x += 1;
               }
               ap->value = ReadAttributeValue(line + x, fileName,
                                              &offset, &lineNumber);
               x += offset;
               if(line[x] == '\"') {
                  x += 1;
               }
            }

         } else {

            /* In tag body; read text. */
            temp = ReadElementValue(line + x, fileName, &offset, &lineNumber);
            x += offset;
            if(temp) {
               if(current) {
                  if(current->value) {
                     current->value = Reallocate(current->value,
                                                 strlen(current->value) +
                                                 strlen(temp) + 1);
                     strcat(current->value, temp);
                     Release(temp);
                  } else {
                     current->value = temp;
                  }
               } else {
                  if(JUNLIKELY(temp[0])) {
                     Warning(_("%s[%u]: unexpected text: \"%s\""),
                             fileName, lineNumber, temp);
                  }
                  Release(temp);
               }
            }
         }
         break;
      }
   }

   return head;
}