Ejemplo n.º 1
0
/* create filesystem menu content */
struct animenucontext *animenu_createfilesystem(char *path, char *regex,
                                                       char *command, int recurse) {

  struct animenucontext *menu;
  struct animenuitem *item;
  DIR *d = NULL;
  struct stat statbuf;
  struct dirent *dirent;
  char *title, *commandall;
  char pathbase[BUFSIZE + 1], pathcur[BUFSIZE + 1];
  unsigned int size;
  struct files {
    char file[PATH_MAX + 1];
    struct files *next;
  } *filecur, *fileroot = NULL, *fileprev = NULL;

  if (path)
    /* path already set, so use that */
    _strncpy(pathbase, path, BUFSIZE + 1);
  else {
    if (regex == NULL) {
      fprintf(stderr, "cannot set base path");
      return(FALSE);
    } else if (*regex != '/') {
      fprintf(stderr, "cannot set base path from '%s', ensure it is fully qualified", regex);
      return(FALSE);
    }
    /* set base path */
    _strncpy(pathbase, regex, BUFSIZE + 1);
    char *rxs;
    if (rx_start(pathbase, &rxs))
      *rxs = '\0';
    /* return pointer to last occurence of char in array
     * and use this to terminate the string */
    *strrchr(pathbase, '/') = '\0';
  }

  if (!(d = opendir(pathbase))) {
    fprintf(stderr, "invalid base path '%s'", pathbase);
    return(FALSE);
  }
  /* fail if we can't allocate enough memory for the menu struct (known size) */
  if (!(menu = malloc(sizeof(struct animenucontext))))
    return(FALSE);
  memset(menu, 0, sizeof(struct animenucontext));

  /* function pointers */
  menu->dispose = animenu_disposemenu;
  menu->next = animenu_next;
  menu->prev = animenu_prev;
  menu->show = animenu_show;
  menu->showcurrent = animenu_showcurrent;
  menu->hide = animenu_hide;
  menu->additem = animenu_additem;

  menu->firstitem = NULL;
  menu->currentitem = NULL;
  menu->osd = NULL;

  for (*pathcur = '\0'; (dirent = readdir(d));) {
    /* use 'back' navigation to move up through the file hierarchy instead */
    if (!strcmp(dirent->d_name, "..") || !strcmp(dirent->d_name, "."))
      continue;

    /* set 'cur' as the current full path for consideration */
    snprintf(pathcur, BUFSIZE + 1, "%s/%s", pathbase, dirent->d_name);

    if (stat(pathcur, &statbuf) != -1) {
      if (S_ISREG(statbuf.st_mode)) {
        if (!rx_compare(pathcur, regex)) {
          /* match the regex path */
          if (!(filecur = malloc(sizeof(struct files))))
            continue;
          if (fileroot == NULL)
            fileroot = filecur;
          else
            fileprev->next = filecur;

          /* copy the path into the file struct's file variable */
          _strncpy(filecur->file, pathcur, BUFSIZE + 1);
          filecur->next = NULL;
          fileprev = filecur;
        }
      } else if (S_ISDIR(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) {
        if (recurse)
          ; /* no-op */
        else {
          /* add the dir/link regardless of match */
          if (!(filecur = malloc(sizeof(struct files))))
            continue;
          if (fileroot == NULL)
            fileroot = filecur;
          else
            fileprev->next = filecur;
          /* copy the path into our struct's file variable */
          _strncpy(filecur->file, pathcur, BUFSIZE + 1);
          filecur->next = NULL;
          fileprev = filecur;
        }
      }
    }
  }
  closedir(d);

  /* create the browse menu's items
   * either 'command' items or 'browse' (menu) items */
  if (!*pathcur) {
    menu->dispose(menu);
    return(FALSE);
  }
  if (fileroot) {
    /* get the final size for the command + args string */
    for (size = strlen(command) + 1, filecur = fileroot; filecur != NULL; filecur = filecur->next)
      size += strlen(filecur->file) + 3;

    if (!(commandall = malloc(size + 1))) {
      menu->dispose(menu);
      return(FALSE);
    }
    _strncpy(commandall, command, size);

    for (filecur = fileroot; filecur != NULL; filecur = filecur->next) {
      _strncat(commandall, " \"", size);
      _strncat(commandall, filecur->file, size);
      _strncat(commandall, "\"", size);
    }

    item = animenu_createitem(animenuitem_command, (char*)playall, NULL, NULL, commandall, 0);
    menu->additem(menu, item);
    for (filecur = fileroot; filecur != NULL; filecur = filecur->next) {
      title = strrchr(filecur->file, '/');
      stat(filecur->file, &statbuf);
      if (S_ISREG(statbuf.st_mode)) {
        /* create command item */
        snprintf(commandall, size, "%s \"%s\"", command, filecur->file);
        item = animenu_createitem(animenuitem_command, ++title, NULL, NULL, commandall, 0);
        menu->additem(menu, item);
      } else if (S_ISDIR(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) {
        /* create menu item */
        item = animenu_createitem(animenuitem_filesystem, title, filecur->file, regex, command, recurse);
        menu->additem(menu, item);
      }
    }
  } else {
    /* create empty item for empty menu */
    item = animenu_createitem(animenuitem_null, NULL, NULL, NULL, NULL, 0);
    menu->additem(menu, item);
  }

  return(menu);
}
Ejemplo n.º 2
0
/*
// ProcessMacro
//
// ps      - Pointer to source file record
// TermCnt - Number of terms (including the command)
// pTerms  - Pointer to the terms
//
// Returns:
//      1 : Success
//      0 : Error
*/
int ProcessMacro( SOURCEFILE *ps, int TermCnt, char **pTerms )
{
    MACRO   *pm;
    int     cidx,sidx,nidx,i;
    char    src[MAX_SOURCE_LINE];
    char    namebuf[MACRO_NAME_LEN];
    char    c;

    pm = MacroFind(pTerms[0]);
    if( !pm )
        return(0);

    if( pm->InUse )
        { Report(ps,REP_ERROR,"Illegal recursive use of macro '%s'",pTerms[0]); return(0); }

    if( pm->Required >= TermCnt )
        { Report(ps,REP_ERROR,"Expected at least %d arguments on '%s'",pm->Required,pTerms[0]); return(0); }

    if( pm->Arguments < (TermCnt-1) )
        { Report(ps,REP_ERROR,"Expected no more than %d arguments on '%s'",pm->Arguments,pTerms[0]); return(0); }

    /* Bump expansion count */
    pm->Expands++;
    pm->InUse = 1;

    for( cidx=0; cidx<pm->CodeLines; cidx++ )
    {
        /* Build the assembly statement */
        sidx=0;
        nidx=0;
        src[0] = 0;
        for(;;)
        {
            c=pm->Code[cidx][sidx++];
            /* Check for start of name */
            if( !nidx )
            {
                if(LabelChar(c,1))
                {
                    namebuf[nidx++]=c;
                    continue;
                }
            }
            /* Else continue a previously started name */
            else
            {
                if(LabelChar(c,0))
                {
                    /* Check for name too long */
                    if( nidx==(MACRO_NAME_LEN-1) )
                        { Report(ps,REP_ERROR,"Term too long in macro assembly text"); pm->InUse=0; return(0); }
                    namebuf[nidx++]=c;
                    continue;
                }

                /* This name is done */
                namebuf[nidx]=0;

                /* Look for an argument match */
                for(i=0;i<pm->Arguments;i++)
                {
                    if(!strcmp(namebuf,pm->ArgName[i]))
                    {
                        /* Match! */
                        if( (i+1)>=TermCnt )
                            _strncat( src, MAX_SOURCE_LINE, pm->ArgDefault[i] );
                        else
                            _strncat( src, MAX_SOURCE_LINE, pTerms[i+1] );
                        goto SUBTEXTDONE;
                    }
                }

                /* Look for a label match */
                for(i=0;i<pm->Labels;i++)
                {
                    if(!strcmp(namebuf,pm->LableName[i]))
                    {
                        char labeltext[TOKEN_MAX_LEN+32];

                        /* Match! */
                        sprintf(labeltext,"_%s_%d_%d_", pm->LableName[i],pm->Id,pm->Expands);
                        _strncat( src, MAX_SOURCE_LINE, labeltext );
                        goto SUBTEXTDONE;
                    }
                }

                /* Sub in the original text */
                _strncat( src, MAX_SOURCE_LINE, namebuf );
SUBTEXTDONE:
                nidx = 0;
            }
            /* Check for text too long */
            i=strlen(src);
            if( i==(MAX_SOURCE_LINE-1) )
                { Report(ps,REP_ERROR,"Macro expansion too long"); pm->InUse=0; return(0); }
            src[i++]=c;
            src[i]=0;
            if( !c )
                break;
        }

        i=strlen(src);
        if(i)
        {
            if( !ProcessSourceLine(ps, i, src) )
            {
                Report(ps,REP_ERROR,"(While expanding code line %d of macro '%s')",(cidx+1),pm->Name);
                pm->InUse=0;
                return(0);
            }
        }
    }
    pm->InUse = 0;
    return(1);
}