/* 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); }
/* // 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); }