home *** CD-ROM | disk | FTP | other *** search
/ Total C++ 2 / TOTALCTWO.iso / vfp5.0 / vfp / tools / convert / conprocs.prg next >
Text File  |  1996-08-21  |  76KB  |  2,499 lines

  1. *- CONPROCS.PRG
  2. *- (c) Microsoft Corporation 1995
  3. *
  4. * This is a procedure file of common file and GENSCRN
  5. * manipulation routines. Routines were taken from 
  6. * GENSCRN and GENSCRNX programs, with additional routines added.
  7.  
  8. #INCLUDE convert.h
  9.  
  10. #DEFINE c_maxwinds        25
  11. #DEFINE c_maxpops         25
  12. #DEFINE c_maxscreens       5
  13.  
  14. *!*****************************************************************************
  15. *!       Function: memofind
  16. *!*****************************************************************************
  17. FUNCTION memofind
  18. * ( borrowed and modified from GENSCRNX - wordsearch )
  19. * ( with permission from Ken Levy )
  20. * Parameters:
  21. *    find_str = expression to search for <expC>
  22. *    searchfld = memo field to seach in    <expC>
  23. *    ignoreword = use exact match?        <expL>
  24. *    returnmline = return line number?   <expL>
  25. *    occurance = occurance to effect     <expN>
  26. *   allafter = return everything        <expL>
  27. *   lNoStrip = don't strip out leading whitespace    <expL>
  28.  
  29. * Returns:
  30. *    returnmline (.F.) ->> char expression following directive
  31. *    returnmline (.T.) ->> line number of expression (was _MLINE)
  32.  
  33. PARAMETERS find_str,searchfld,ignoreword,returnmline,occurance,allafter,lNoStrip
  34.  
  35. PRIVATE memodata,memline,memline2,str_data,lastmline
  36. PRIVATE matchcount,linecount,linecount2,at_mline,at_mline2,mline2
  37. PRIVATE lf_pos,lf_pos2,at_pos
  38.  
  39. LOCAL m.memodata2
  40.  
  41. IF TYPE('m.returnmline')=='N'
  42.   m.returnmline=.T.
  43. ENDIF
  44.  
  45. IF TYPE("m.allafter") # "L"
  46.     m.allafter = .F.
  47. ENDIF
  48.  
  49. DO CASE
  50.   CASE TYPE('m.occurance')#'N'
  51.     m.occurance=1
  52.   CASE m.occurance<0
  53.     RETURN IIF(m.returnmline,0,C_NULL)
  54. ENDCASE
  55.  
  56. * check if memo is empty
  57. m.memodata=EVALUATE(m.searchfld)
  58. IF EMPTY(m.searchfld) OR EMPTY(m.memodata) OR m.memodata==C_NULL
  59.     RETURN IIF(m.returnmline,0,C_NULL)
  60. ENDIF
  61.  
  62. * initialize vars
  63. m.memline2=''
  64. m.lastmline=_MLINE
  65. m.at_mline=0
  66. m.at_mline2=0
  67. m.mline2=0
  68. m.lf_pos=0
  69. m.lf_pos2=0
  70. m.matchcount=0
  71. m.linecount=0
  72. m.linecount2=0
  73.  
  74. *- be brutal -- strip out all indents and line feeds
  75. IF !lNoStrip
  76.     memodata = CleanWhite(m.memodata)
  77. ENDIF
  78.  
  79. *-SUSPEND
  80. m.memodata=C_CR+m.memodata
  81. _MLINE=ATC(C_CR+m.find_str,m.memodata)
  82. IF _MLINE=0
  83.     _MLINE=m.lastmline
  84.     RETURN IIF(m.returnmline,0,C_NULL)
  85. ENDIF
  86.  
  87. m.memodata2 = m.memodata            && remember it in its pristine form
  88.  
  89. DO WHILE .T.
  90.   DO CASE
  91.     CASE m.occurance>0 AND _MLINE>=LEN(m.memodata)
  92.       EXIT
  93.     CASE _MLINE>=LEN(m.memodata)
  94.       m.occurance=-1
  95.     OTHERWISE
  96.       m.at_mline=_MLINE
  97.       m.memline=ALLTRIM(MLINE(m.memodata,1,_MLINE))
  98.       m.lf_pos=AT(C_LF,SUBSTR(m.memodata,m.at_mline+1,LEN(m.memline)))
  99.       IF m.lf_pos>0
  100.         m.memline=ALLTRIM(LEFT(m.memline,m.lf_pos-1))
  101.       ENDIF
  102.       
  103.       IF LEN(m.memline) < LEN(m.find_str)+1
  104.         m.str_data = ""
  105.       ELSE
  106.         m.str_data=SUBSTR(m.memline,LEN(m.find_str)+1,1)
  107.       ENDIF
  108.       
  109.       m.at_pos=ATC(m.find_str,m.memline)
  110.       IF m.at_pos#1 OR (!m.ignoreword AND !EMPTY(m.str_data))
  111.         m.at_pos=0
  112.         m.memodata=C_LF+SUBSTR(m.memodata,_MLINE)
  113.         _MLINE=ATC(C_LF+m.find_str,m.memodata)
  114.         IF _MLINE>0
  115.           LOOP
  116.         ENDIF
  117.         m.memodata=C_CR+SUBSTR(m.memodata,2)
  118.         _MLINE=ATC(C_CR+m.find_str,m.memodata)
  119.         IF _MLINE>0
  120.           LOOP
  121.         ENDIF
  122.         IF m.occurance>0
  123.           EXIT
  124.         ENDIF
  125.       ENDIF
  126.       m.matchcount=m.matchcount+1
  127.       IF m.matchcount<m.occurance OR m.occurance=0
  128.         IF m.at_pos=1 AND (m.ignoreword OR EMPTY(m.str_data))
  129.           m.mline2=_MLINE
  130.           m.at_mline2=m.at_mline
  131.           m.memline2=m.memline
  132.           m.lf_pos2=m.lf_pos
  133.           m.linecount2=m.linecount
  134.         ENDIF
  135.         IF BETWEEN(_MLINE,1,LEN(m.memodata))
  136.           _MLINE=_MLINE-2
  137.           m.linecount=m.linecount+_MLINE
  138.           LOOP
  139.         ENDIF
  140.       ENDIF
  141.   ENDCASE
  142.   IF m.occurance<=0
  143.     IF m.mline2=0
  144.       RETURN IIF(m.returnmline,0,C_NULL)
  145.     ENDIF
  146.     _MLINE=m.mline2
  147.     m.at_mline=m.at_mline2
  148.     m.memline=m.memline2
  149.     m.lf_pos=m.lf_pos2
  150.     m.linecount=m.linecount2
  151.     m.occurance=1
  152.   ENDIF
  153.   m.mline2=_MLINE
  154.   _MLINE=m.lastmline
  155.   m.at_pos=0
  156.   m.str_data=SUBSTR(m.memline,LEN(m.find_str)+1)
  157.   IF m.ignoreword AND !LEFT(m.str_data,1)==' ' ;
  158.       AND !m.allafter
  159.     m.at_pos=AT(' ',m.str_data)
  160.     IF m.at_pos>0
  161.       m.str_data=SUBSTR(m.str_data,m.at_pos+1)
  162.     ENDIF
  163.   ENDIF
  164.   m.str_data=ALLTRIM(m.str_data)
  165.   IF !m.returnmline
  166.     RETURN m.str_data
  167.   ENDIF
  168.   m.returnmline=m.mline2-m.at_mline+1-IIF(m.lf_pos>0,1,0)
  169.   *-RETURN m.at_mline+m.linecount
  170.   RETURN OCCURS(C_CR,LEFT(m.memodata2,m.at_mline+m.linecount))
  171. ENDDO
  172.  
  173. _MLINE=m.lastmline
  174. RETURN IIF(m.returnmline,0,C_NULL)
  175.  
  176. * END
  177.  
  178. *!*****************************************************************************
  179. *!       Function: memostuff
  180. *!*****************************************************************************
  181. FUNCTION memostuff
  182. * ( borrowed and modified from GENSCRNX - wordstuff )
  183. * ( with permission from Ken Levy )
  184. * Parameters:
  185. *    stuff_str = expression to search for     <expC>
  186. *    searchfld = memo field to seach in        <expC>
  187. *    replace_str = expr to replace with        <exprC>
  188. *    insflag = directive line added/removed    <expL>
  189. *    insbefore = insert at beginning of snippet    <expL>
  190. *    occurance = occurance to effect         <expN>
  191.  
  192. * Returns:
  193. *    .T. if successful
  194.  
  195. PARAMETERS stuff_str,searchfld,replace_str,insflag,insbefore,occurance
  196.  
  197. PRIVATE var_type,memodata,memline,snptname
  198. PRIVATE at_pos,lf_pos,str_len,remove_str,sub_str
  199.  
  200. LOCAL cTmp, nLine
  201.  
  202. IF TYPE('m.insflag')=='N'
  203.   m.insflag=(m.insflag=1)
  204. ENDIF
  205.  
  206. m.sub_str = IIF(TYPE('m.replace_str')='C',m.replace_str,m.stuff_str)
  207.  
  208. m.memodata=EVALUATE(m.searchfld)
  209. m.stuff_str=ALLTRIM(m.stuff_str)
  210.  
  211. * Remove excess CRLF from top of snippet
  212. DO WHILE LEFT(m.memodata,1)==C_CR OR LEFT(m.memodata,1)==C_LF
  213.   m.memodata=SUBSTR(m.memodata,2)
  214. ENDDO
  215. REPLACE (m.searchfld) WITH m.memodata
  216.  
  217. m.remove_str=m.stuff_str
  218. m.at_pos=AT(' ',m.remove_str)
  219. IF m.at_pos>0
  220.   m.remove_str=ALLTRIM(LEFT(m.remove_str,m.at_pos-1))
  221. ENDIF
  222. m.str_len=0
  223.  
  224. *- memofind now returns the LINE NUMBER, not the _MLINE position. So calculate
  225. * _MLINE from the line number
  226. nLine = memofind(m.remove_str,m.searchfld,.T.,.T.,m.occurance) - 1
  227. cTmp = MLINE(m.memodata,m.nLine)
  228. m.at_pos = _MLINE + IIF(SUBS(memodata,_MLINE,2) = C_CRLF,2,1)
  229. cTmp = MLINE(m.memodata,m.nLine + 1)
  230. str_len = _MLINE - m.at_pos + 1
  231. *-m.at_pos=memofind(m.remove_str,m.searchfld,.T.,@m.str_len,m.occurance)
  232. IF m.at_pos=0 OR m.str_len=0
  233.   m.at_pos=0
  234. ENDIF
  235.  
  236. IF m.at_pos>0
  237.   m.memline=SUBSTR(m.memodata,m.at_pos,m.str_len)
  238.   m.lf_pos=AT(C_LF,m.memline)
  239.   IF m.lf_pos>0
  240.     m.str_len=m.lf_pos
  241.   ENDIF
  242.   m.memodata=LEFT(m.memodata,m.at_pos-1)+SUBSTR(m.memodata,m.at_pos+m.str_len)
  243. ENDIF
  244.  
  245. IF !m.insflag
  246.   IF m.at_pos=0
  247.     RETURN .F.
  248.   ENDIF
  249.   IF UPPER(LEFT(m.searchfld,2))=='M.'
  250.     &searchfld=m.memodata
  251.   ELSE
  252.     REPLACE (m.searchfld) WITH m.memodata
  253.   ENDIF
  254.   RETURN .T.
  255. ENDIF
  256.  
  257. DO CASE
  258.   CASE m.at_pos>0
  259.     m.stuff_str=LEFT(m.memodata,m.at_pos-1)+m.sub_str+C_CR+;
  260.                 SUBSTR(m.memodata,m.at_pos)
  261.   CASE m.insbefore
  262.     IF !EMPTY(m.memodata)
  263.       m.memodata=C_CR+m.memodata
  264.     ENDIF
  265.     m.stuff_str=m.sub_str+m.memodata
  266.   OTHERWISE
  267.     IF !EMPTY(m.memodata) AND !RIGHT(m.memodata,1)==C_CRLF AND ;
  268.        !RIGHT(m.memodata,1)==C_LF
  269.       m.memodata=m.memodata+C_CR
  270.     ENDIF
  271.     DO WHILE RIGHT(m.memodata,1)==C_CR OR RIGHT(m.memodata,1)==C_LF
  272.       m.memodata=LEFT(m.memodata,LEN(m.memodata)-1)
  273.     ENDDO
  274.     m.stuff_str=m.memodata+C_CR+m.sub_str+C_CR
  275. ENDCASE
  276. DO WHILE RIGHT(m.stuff_str,1)==C_CR OR RIGHT(m.stuff_str,1)==C_LF
  277.   m.stuff_str=LEFT(m.stuff_str,LEN(m.stuff_str)-1)
  278. ENDDO
  279. m.stuff_str=m.stuff_str+C_CR
  280. IF UPPER(LEFT(m.searchfld,2))=='M.'
  281.   &searchfld=m.stuff_str
  282. ELSE
  283.   REPLACE (m.searchfld) WITH m.stuff_str
  284. ENDIF
  285. RETURN .T.
  286.  
  287. * END wordstuff
  288.  
  289.  
  290. *!*****************************************************************************
  291. *!       Function: GENPROC
  292. *!*****************************************************************************
  293. PROCEDURE genproc
  294.  
  295.  
  296. *PRIVATE ALL LIKE g_*
  297.  
  298. * g_firstproc holds the line number of the first PROCEDURE or FUNCTION in
  299. * the cleanup snippet of each screen.
  300. DIMENSION g_firstproc[C_MAXSCREENS]
  301. g_firstproc = 0
  302.  
  303. DIMENSION g_platlist[C_MAXPLATFORMS]
  304. g_platlist[1] = c_dos
  305. g_platlist[2] = c_windows
  306. g_platlist[3] = c_mac
  307. g_platlist[4] = c_unix
  308.  
  309. DIMENSION g_procs[1,C_MAXPLATFORMS+3]
  310. * First column is a procedure name
  311. * Second through n-th column is the line number in the cleanup snippet where
  312. *    a procedure with this name starts.
  313. * C_MAXPLATFORMS+2 column is a 1 if this procedure has been emitted.
  314. * C_MAXPLATFORMS+3 column holds the parameter statement, if any.
  315. * One row for each unique procedure name found in the cleanup snippet for any platform.
  316. g_procs = -1
  317. g_procs[1,1] = ""
  318. g_procs[1,C_MAXPLATFORMS+3] = ""
  319. g_procnames = 0   && the number we've found so far
  320. g_tabchr = ""
  321.  
  322. SCAN FOR objtype = 1 AND isgenplat(platform)
  323.     DO updprocarray
  324. ENDSCAN
  325.  
  326. SCAN FOR objtype = 1 AND isgenplat(platform)
  327.     IF EMPTY(proccode)
  328.        LOOP
  329.     ENDIF
  330.     DO extractprocs WITH 1
  331. ENDSCAN
  332.  
  333. RETURN
  334.  
  335. *!*****************************************************************************
  336. *!       Function: GETFIRSTLINE
  337. *!*****************************************************************************
  338. FUNCTION getfirstline
  339. *)
  340. *) Find first line # in snippet for:
  341. *) 1. PROCEDURE or FUNCTION statement in a cleanup
  342. *) 2. PARAMETER statement
  343. *) 3. SECTION1/2
  344. PARAMETER m.snipname,m.sniptype,m.sectnum
  345. PRIVATE proclineno, numlines, word1
  346. _MLINE = 0
  347. m.numlines = MEMLINES(&snipname)
  348. FOR m.proclineno = 1 TO m.numlines
  349.    m.line  = MLINE(&snipname, 1, _MLINE)
  350.    DO killcr WITH m.line
  351.    m.line  = UPPER(LTRIM(STRTRAN(m.line,C_TAB,' ')))
  352.    m.word1 = wordnum(m.line,1)
  353.    DO CASE
  354.    CASE m.sniptype = "PARM"
  355.      IF !EMPTY(m.word1) AND match(m.word1,"PARAMETERS")
  356.        RETURN m.proclineno
  357.      ENDIF
  358.    CASE m.sniptype = "SECT"
  359.      IF !EMPTY(m.word1) AND LEFT(m.line,5) = "#SECT" ; 
  360.            AND AT(m.sectnum,m.line) # 0
  361.        RETURN m.proclineno
  362.      ENDIF
  363.    CASE m.sniptype = "PROC"
  364.      IF !EMPTY(m.word1) AND (match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION"))
  365.        RETURN m.proclineno
  366.      ENDIF
  367.    ENDCASE  
  368. ENDFOR
  369. RETURN 0
  370.  
  371.  
  372. *!*****************************************************************************
  373. *!       Function: wordnum
  374. *!*****************************************************************************
  375. FUNCTION wordnum
  376. *)
  377. *) WORDNUM - Returns w_num-th word from string strg
  378. *)
  379. PARAMETERS m.strg,m.w_num
  380. PRIVATE strg,s1,w_num,ret_str
  381.  
  382. m.s1 = ALLTRIM(m.strg)
  383.  
  384. * Replace tabs with spaces
  385. m.s1 = CHRTRANC(m.s1,CHR(9)," ")
  386.  
  387. * Reduce multiple spaces to a single space
  388. DO WHILE AT('  ',m.s1) > 0
  389.    m.s1 = STRTRAN(m.s1,'  ',' ')
  390. ENDDO
  391.  
  392. ret_str = ""
  393. DO CASE
  394. CASE m.w_num > 1
  395.    DO CASE
  396.    CASE AT(" ",m.s1,m.w_num-1) = 0   && No word w_num.  Past end of string.
  397.       m.ret_str = ""
  398.    CASE AT(" ",m.s1,m.w_num) = 0     && Word w_num is last word in string.
  399.       m.ret_str = SUBSTR(m.s1,AT(" ",m.s1,m.w_num-1)+1,255)
  400.    OTHERWISE                         && Word w_num is in the middle.
  401.       m.strt_pos = AT(" ",m.s1,m.w_num-1)
  402.       m.ret_str  = SUBSTR(m.s1,strt_pos,AT(" ",m.s1,m.w_num)+1 - strt_pos)
  403.    ENDCASE
  404. CASE m.w_num = 1
  405.    IF AT(" ",m.s1) > 0               && Get first word.
  406.       m.ret_str = SUBSTR(m.s1,1,AT(" ",m.s1)-1)
  407.    ELSE                              && There is only one word.  Get it.
  408.       m.ret_str = m.s1
  409.    ENDIF
  410. ENDCASE
  411. RETURN ALLTRIM(m.ret_str)
  412.  
  413. *!*****************************************************************************
  414. *!      PROCEDURE: KILLCR
  415. *!*****************************************************************************
  416. PROCEDURE killcr
  417. PARAMETER m.strg
  418. IF _MAC
  419.    m.strg = CHRTRANC(m.strg,CHR(13)+CHR(10),"")
  420. ENDIF
  421. RETURN
  422.  
  423. *!*****************************************************************************
  424. *!       Function: MATCH
  425. *!*****************************************************************************
  426. FUNCTION match
  427. *)
  428. *) MATCH - Returns TRUE if candidate is a valid 4-or-more-character abbreviation of keyword
  429. *)
  430. PARAMETER m.candidate, m.keyword
  431. PRIVATE m.in_exact, m.retlog
  432.  
  433. m.in_exact = SET("EXACT")
  434. SET EXACT OFF
  435. DO CASE
  436. CASE EMPTY(m.candidate)
  437.    m.retlog = EMPTY(m.keyword)
  438. CASE LEN(m.candidate) < 4
  439.    m.retlog = IIF(m.candidate == m.keyword,.T.,.F.)
  440. OTHERWISE
  441.    m.retlog = IIF(m.keyword = m.candidate,.T.,.F.)
  442. ENDCASE
  443. IF m.in_exact != "OFF"
  444.    SET EXACT ON
  445. ENDIF
  446.  
  447. RETURN m.retlog
  448.  
  449. *!*****************************************************************************
  450. *!
  451. *!       Function: GETPARAM
  452. *!
  453. *!      Called by: CHECKPARAM()       (function  in GENSCRN.PRG)
  454. *!
  455. *!          Calls: ISCOMMENT()        (function  in GENSCRN.PRG)
  456. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  457. *!               : MATCH()            (function  in GENSCRN.PRG)
  458. *!
  459. *!*****************************************************************************
  460. FUNCTION getparam
  461. *)
  462. *) GETPARAM - Return the PARAMETER statement from a setup snippet, if one is there
  463. *)
  464. PARAMETER m.snipname
  465. PRIVATE m.i, m.thisparam, m.numlines, m.thisline, m.word1, m.contin
  466.  
  467. m.g_dblampersand = CHR(38) + CHR(38)   && used in some tight loops.  Concatenate just once here.
  468.  
  469. * Do a quick check to see if we need to search further.
  470. IF ATC("PARA",&snipname) = 0
  471.    RETURN ""
  472. ENDIF
  473.  
  474. m.numlines = MEMLINES(&snipname)
  475. _MLINE = 0
  476. m.i = 1
  477. DO WHILE m.i <= m.numlines
  478.    m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  479.    DO killcr WITH m.thisline
  480.  
  481.    * Drop any double-ampersand comment
  482.    IF AT(m.g_dblampersand,m.thisline) > 0
  483.       m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  484.    ENDIF
  485.  
  486.    IF !EMPTY(m.thisline) AND !iscomment(@thisline)
  487.       * See if the first non-blank, non-comment, non-directive, non-EXTERNAL
  488.       * line is a #SECTION 1
  489.       DO CASE
  490.       CASE LEFT(m.thisline,5) = "#SECT" AND AT('1',m.thisline) <> 0
  491.          * Read until we find a #SECTION 2, the end of the snippet or a
  492.          * PARAMETER statement.
  493.          DO WHILE m.i <= m.numlines
  494.             m.thisline = UPPER(LTRIM(MLINE(&snipname, 1, _MLINE)))
  495.             DO killcr WITH m.thisline
  496.  
  497.             * Drop any double-ampersand comment
  498.             IF AT(m.g_dblampersand,m.thisline) > 0
  499.                m.thisline = LEFT(m.thisline,AT(m.g_dblampersand,m.thisline)-1)
  500.             ENDIF
  501.  
  502.             m.word1 = wordnum(CHRTRANC(m.thisline,CHR(9)+';',' '),1)
  503.             DO CASE
  504.             CASE match(m.word1,"PARAMETERS")
  505.  
  506.                * Replace tabs with spaces
  507.                m.thisline = LTRIM(CHRTRANC(m.thisline,CHR(9)," "))
  508.  
  509.                * Process continuation lines.  Replace tabs in incoming lines with spaces.
  510.                DO WHILE RIGHT(RTRIM(m.thisline),1) = ';'
  511.                   m.thisline = m.thisline + ' '+ CHR(13)+CHR(10)+CHR(9)
  512.                   m.contin = MLINE(&snipname, 1, _MLINE)
  513.                   DO killcr WITH m.contin
  514.                   m.contin = CHRTRANC(LTRIM(m.contin),CHR(9)," ")
  515.                   m.thisline = m.thisline + UPPER(m.contin)
  516.                ENDDO
  517.  
  518.                * Clean up the parameters so that minor differences in
  519.                * spacing don't cause the comparisons to fail.
  520.  
  521.                * Take the parameters but not the PARAMETER keyword itself
  522.                m.thisparam = SUBSTR(m.thisline,AT(' ',m.thisline)+1)
  523.                DO WHILE INLIST(LEFT(m.thisparam,1),CHR(10),CHR(13),CHR(9),' ')
  524.                   m.thisparam = SUBSTR(m.thisparam,2)
  525.                ENDDO
  526.  
  527.                * Force single spacing in the param string
  528.                DO WHILE AT('  ',m.thisparam) > 0
  529.                   m.thisparam = STRTRAN(m.thisparam,'  ',' ')
  530.                ENDDO
  531.  
  532.                * Drop "m." designations so that they don't make the variables look different
  533.                m.thisparam = STRTRAN(m.thisparam,'m.','')
  534.                m.thisparam = STRTRAN(m.thisparam,'M.','')
  535.                m.thisparam = STRTRAN(m.thisparam,'m->','')
  536.                m.thisparam = STRTRAN(m.thisparam,'M->','')
  537.  
  538.                RETURN LOWER(m.thisparam)
  539.             CASE LEFT(m.thisline,5) = "#SECT" AND AT('2',m.thisline) <> 0
  540.                * No parameter statement, since we found #SECTION 2 first
  541.                RETURN ""
  542.             ENDCASE
  543.             m.i = m.i + 1
  544.          ENDDO
  545.       CASE LEFT(m.thisline,1) = "#"   && some other directive
  546.          * Do nothing.  Get next line.
  547.       CASE match(wordnum(m.thisline,1),"EXTERNAL")
  548.          * Ignore it.  This doesn't disqualify a later statement from being a PARAMETER
  549.          * statement.
  550.       OTHERWISE
  551.          * no #SECTION 1, so no parameters
  552.          RETURN ""
  553.       ENDCASE
  554.    ENDIF
  555.    m.i = m.i + 1
  556. ENDDO
  557. RETURN ""
  558.  
  559.  
  560. *!*****************************************************************************
  561. *!
  562. *!       Function: ISCOMMENT
  563. *!
  564. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  565. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  566. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  567. *!               : GETPARAM()         (function  in GENSCRN.PRG)
  568. *!
  569. *!*****************************************************************************
  570. FUNCTION iscomment
  571. *)
  572. *) ISCOMMENT - Determine if textline is a comment line.
  573. *)
  574. PARAMETER m.textline
  575. PRIVATE m.asterisk, m.isnote, m.ampersand, m.statement
  576. IF EMPTY(m.textline)
  577.    RETURN .F.
  578. ENDIF
  579. m.statement = UPPER(LTRIM(m.textline))
  580.  
  581. m.asterisk  = AT("*", m.statement)
  582. m.ampersand = AT(m.g_dblampersand, m.statement)
  583. m.isnote    = AT("NOTE", m.statement)
  584.  
  585. DO CASE
  586. CASE (m.asterisk = 1 OR m.ampersand = 1)
  587.    RETURN .T.
  588. CASE (m.isnote = 1 ;
  589.       AND (LEN(m.statement) <= 4 OR SUBSTR(m.statement,5,1) = ' '))
  590.    * Don't be fooled by something like "notebook = 7"
  591.    RETURN .T.
  592. ENDCASE
  593. RETURN .F.
  594.  
  595. *!*****************************************************************************
  596. *!
  597. *!       Function: ISPARAMETER
  598. *!
  599. *!      Called by: WRITECODE          (procedure in GENSCRN.PRG)
  600. *!
  601. *!          Calls: MATCH()            (function  in GENSCRN.PRG)
  602. *!               : WORDNUM()          (function  in GENSCRN.PRG)
  603. *!
  604. *!*****************************************************************************
  605. FUNCTION isparameter
  606. *)
  607. *) ISPARAMETER - Determine if strg is a PARAMETERS statement
  608. *)
  609. PARAMETER m.strg
  610. PRIVATE m.ispar
  611. m.ispar = .F.
  612. IF !EMPTY(strg) AND match(CHRTRANC(wordnum(strg,1),';',''),"PARAMETERS")
  613.    m.ispar = .T.
  614. ENDIF
  615. RETURN m.ispar
  616.  
  617.  
  618. *!*****************************************************************************
  619. *!
  620. *!       Function: PROCSMATCH
  621. *!
  622. *!*****************************************************************************
  623. FUNCTION procsmatch
  624. *)
  625. *) PROCSMATCH - Are the CRCs for the cleanup snippets the same for all platforms in the
  626. *)                current screen that are being generated?
  627. *)
  628. PRIVATE m.crccode, m.thiscode, m.in_rec
  629.  
  630. m.in_rec = IIF(!EOF(),RECNO(),1)
  631. m.crccode = "0"
  632. * Get the headers for all the platforms we are generating
  633. SCAN FOR objtype = 1 AND isgenplat(platform)
  634.    m.thiscode = ALLTRIM(SYS(2007,proccode))
  635.    DO CASE
  636.    CASE m.crccode = "0"
  637.       m.crccode = m.thiscode
  638.    CASE m.thiscode <> m.crccode AND m.crccode <> "0"
  639.       RETURN .F.
  640.    ENDCASE
  641. ENDSCAN
  642. GOTO m.in_rec
  643. RETURN .T.
  644.  
  645. *!*****************************************************************************
  646. *!
  647. *!       Function: ISGENPLAT
  648. *!
  649. *!      Called by: GENPROCEDURES      (procedure in GENSCRN.PRG)
  650. *!               : PROCSMATCH()       (function  in GENSCRN.PRG)
  651. *!
  652. *!*****************************************************************************
  653. FUNCTION isgenplat
  654. *)
  655. *) ISGENPLAT - Is this platform one of the ones being generated?
  656. *)
  657. PARAMETER m.platname
  658. RETURN IIF(ASCAN(g_platforms,ALLTRIM(UPPER(m.platname))) > 0, .T. , .F. )
  659.  
  660.  
  661.  
  662. *!*****************************************************************************
  663. *!
  664. *!       Function: CLEANPARAM
  665. *!
  666. *!*****************************************************************************
  667. FUNCTION cleanparam
  668. *)
  669. *) CLEANPARAM - Clean up a parameter string so that it may be compared with another one.
  670. *)              This function replaces tabs with spaces, capitalizes the string, merges
  671. *)              forces single spacing, and strips out CR/LF characters.
  672. *)
  673. PARAMETER m.p, m.cp
  674. m.cp = UPPER(ALLTRIM(CHRTRANC(m.p,";"+CHR(13)+CHR(10),"")))   && drop CR/LF and continuation chars
  675. m.cp = CHRTRANC(m.cp,CHR(9),' ')   && tabs to spaces
  676. DO WHILE AT('  ',m.cp) > 0         && reduce multiple spaces to a single space
  677.    m.cp = STRTRAN(m.cp,'  ',' ')
  678. ENDDO
  679. DO WHILE AT(', ',m.cp) > 0         && drop spaces after commas
  680.    m.cp = STRTRAN(m.cp,', ',',')
  681. ENDDO
  682. RETURN m.cp
  683.  
  684. *!*****************************************************************************
  685. *!
  686. *!      Procedure: ADDPROCNAME
  687. *!
  688. *!      Called by: UPDPROCARRAY       (procedure in GENSCRN.PRG)
  689. *!
  690. *!          Calls: GETPLATNUM()       (function  in GENSCRN.PRG)
  691. *!
  692. *!*****************************************************************************
  693. PROCEDURE addprocname
  694. *)
  695. *) ADDPROCNAME - Update g_procs with pname data
  696. *)
  697. PARAMETER m.pname, m.platname, m.linenum, m.lastmline
  698. PRIVATE m.rnum, m.platformcol, m.i, m.j
  699. IF EMPTY(m.pname)
  700.    RETURN
  701. ENDIF
  702.  
  703. * Look up this name in the procedures array
  704. m.rnum = 0
  705. FOR m.i = 1 TO m.g_procnames
  706.    IF g_procs[m.i,1] == m.pname
  707.       m.rnum = m.i
  708.       EXIT
  709.    ENDIF
  710. ENDFOR
  711.  
  712. IF m.rnum = 0
  713.    * New name
  714.    g_procnames = m.g_procnames + 1
  715.    DIMENSION g_procs[m.g_procnames,C_MAXPLATFORMS+3]
  716.    g_procs[m.g_procnames,1] = UPPER(ALLTRIM(m.pname))
  717.    FOR m.j = 1 TO c_maxplatforms
  718.       g_procs[m.g_procnames,m.j + 1] = -1
  719.    ENDFOR
  720.    g_procs[m.g_procnames,C_MAXPLATFORMS+2] = .F.   && not emitted yet
  721.    g_procs[m.g_procnames,C_MAXPLATFORMS+3] = ""    && parameter statement
  722.    m.rnum = m.g_procnames
  723. ENDIF
  724.  
  725. m.platformcol = getplatnum(m.platname) + 1
  726. IF m.platformcol > 1
  727.    g_procs[m.rnum, m.platformcol] = m.lastmline
  728. ENDIF
  729. RETURN
  730.  
  731. *!*****************************************************************************
  732. *!
  733. *!       Function: GETPLATNUM
  734. *!
  735. *!      Called by: PREPWNAMES         (procedure in GENSCRN.PRG)
  736. *!               : ADDPROCNAME        (procedure in GENSCRN.PRG)
  737. *!               : WRITECODE          (procedure in GENSCRN.PRG)
  738. *!               : WRITELINE          (procedure in GENSCRN.PRG)
  739. *!               : ADDTOCTRL          (procedure in GENSCRN.PRG)
  740. *!
  741. *!*****************************************************************************
  742. FUNCTION getplatnum
  743. *)
  744. *) GETPLATNUM - Return the g_platlist array index given a platform name
  745. *)
  746. PARAMETER m.platname
  747. PRIVATE m.i
  748. FOR m.i = 1 TO c_maxplatforms
  749.    IF g_platlist[m.i] == UPPER(ALLTRIM(m.platname))
  750.       RETURN m.i
  751.    ENDIF
  752. ENDFOR
  753. RETURN 0
  754.  
  755.  
  756.  
  757. *!*****************************************************************************
  758. *!
  759. *!      Procedure: EXTRACTPROCS
  760. *!
  761. *!*****************************************************************************
  762. PROCEDURE extractprocs
  763. *)
  764. *) EXTRACTPROCS - Output the procedures for the current platform in the current screen
  765. *)
  766. * We only get here if we are emitting for multiple platforms and the cleanup snippets
  767. * for all platforms are not identical.  We are positioned on a screen header record for
  768. * the g_genvers platform.
  769.  
  770. *- NOTE: Also called if multiple procs in a VALID or other snippet
  771. *- If passed, snipname is memo field to go through. Otherwise, set to "proccode"
  772.  
  773. PARAMETER m.scrnno, m.snipname
  774.  
  775. PRIVATE m.hascontin, m.iscontin, m.sniplen, m.i, m.thisline, m.pnum, m.word1, m.word2
  776.  
  777. IF PARAMETERS() = 1
  778.     m.snipname = "proccode"
  779. ENDIF
  780.  
  781. _MLINE = 0
  782. m.sniplen   = LEN(&snipname)
  783. m.numlines  = MEMLINES(&snipname)
  784. m.hascontin = .F.
  785. DO WHILE _MLINE < m.sniplen
  786.    m.thisline  = UPPER(ALLTRIM(MLINE(&snipname,1, _MLINE)))
  787.    DO killcr WITH m.thisline
  788.    m.iscontin  = m.hascontin
  789.    m.hascontin = RIGHT(m.thisline,1) = ';'
  790.    IF LEFT(m.thisline,1) $ "PF" AND !m.iscontin
  791.       m.word1 = wordnum(m.thisline, 1)
  792.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  793.          m.word2 = wordnum(m.thisline,2)
  794.          * Does this procedure have a name conflict?
  795.          IF PARAMETERS() = 1
  796.             m.pnum = getprocnum(m.word2)
  797.             IF pnum > 0 
  798.                 DO CASE
  799.                     CASE g_procs[m.pnum,C_MAXPLATFORMS+2]
  800.                        * This one has already been generated.  Skip past it now.
  801.                        DO emitproc WITH .F., m.thisline, m.sniplen, m.scrnno, m.snipname
  802.                        LOOP
  803.                     CASE hasconflict(m.pnum)
  804.                        * Name collision detected.  Output bracketed code for all platforms
  805.                        DO emitbracket WITH m.pnum, m.scrnno
  806.                     OTHERWISE
  807.                        * This procedure has no name collision and has not been emitted yet.
  808.                        DO emitproc WITH .T., m.thisline, m.sniplen, m.scrnno, m.snipname
  809.                 ENDCASE
  810.                 g_procs[pnum,C_MAXPLATFORMS+2] = .T.
  811.             ENDIF &&  pnum > 0
  812.          ELSE
  813.            *- special case, called for VALID or WHEN
  814.            *- Welcome to Kludge City
  815.            g_tabchr = ""
  816.             DIMENSION g_platforms[1]
  817.             STORE "" TO g_platforms
  818.             DIMENSION g_platlist[C_MAXPLATFORMS]
  819.             g_platlist[1] = c_dos
  820.             g_platlist[2] = c_windows
  821.             g_platlist[3] = c_mac
  822.             g_platlist[4] = c_unix
  823.            DO emitproc WITH .T., m.thisline, m.sniplen, m.scrnno, m.snipname
  824.          ENDIF && PARAMETERS() = 1
  825.       ENDIF
  826.    ENDIF
  827. ENDDO
  828. RETURN
  829.  
  830. *!*****************************************************************************
  831. *!
  832. *!      Procedure: EMITPROC
  833. *!
  834. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  835. *!
  836. *!*****************************************************************************
  837. PROCEDURE emitproc
  838. *)
  839. *) EMITPROC - Scan through the next procedure/function in the current cleanup snippet.
  840. *)            If dowrite is TRUE, emit the code as we go.  Otherwise, just skip over it
  841. *)            and advance _MLINE.
  842. *)
  843. * We are positioned on the PROCEDURE or FUNCTION line now and there isn't a name
  844. * conflict.
  845. PARAMETER m.dowrite, m.thisline, m.sniplen, m.scrnno, m.snipname
  846. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  847.    m.iscontin, m.hascontin, m.platnum
  848.  
  849. m.hascontin = .F.
  850. m.done = .F.
  851.  
  852. * Write the PROCEDURE/FUNCTION statement
  853. m.upline = UPPER(ALLTRIM(CHRTRANC(m.thisline,chr(9),' ')))
  854.  
  855. m.g_genvers = g_platforms[1]
  856.  
  857. m.platnum = getplatnum(m.g_genvers)
  858.  
  859. IF m.dowrite    && actually emit the procedure?
  860.    DO writeline WITH m.thisline, m.g_genvers, m.platnum, m.upline, m.scrnno
  861. ENDIF
  862.  
  863. * Write the body of the procedure
  864. DO WHILE !m.done AND _MLINE < m.sniplen
  865.    m.lastmline = _MLINE          && note where this line started
  866.  
  867.    m.line = MLINE(&snipname,1, _MLINE)
  868.    DO killcr WITH m.line
  869.    m.upline = UPPER(ALLTRIM(CHRTRANC(m.line,chr(9),' ')))
  870.  
  871.    m.iscontin = m.hascontin
  872.    m.hascontin = RIGHT(m.upline,1) = ';'
  873.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  874.       m.word1 = wordnum(m.upline, 1)
  875.       IF match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  876.          done = .T.
  877.          _MLINE = m.lastmline    && drop back one line and stop writing
  878.          LOOP
  879.       ENDIF
  880.    ENDIF
  881.  
  882.    IF m.dowrite    && actually emit the procedure?
  883.       DO writeline WITH m.line, m.g_genvers, m.platnum, m.upline, m.scrnno
  884.    ENDIF
  885.  
  886. ENDDO
  887. RETURN && emitproc
  888.  
  889. *!*****************************************************************************
  890. *!
  891. *!      Procedure: EMITBRACKET
  892. *!
  893. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  894. *!
  895. *!*****************************************************************************
  896. PROCEDURE emitbracket
  897. *)
  898. *) EMITBRACKET - Emit DO CASE/CASE _DOS brackets and call putproc to emit code for this procedure
  899. *)
  900. PARAMETER m.pnum, m.scrnno
  901. PRIVATE m.word1, m.word2, m.line, m.upline, m.done, m.lastmline, ;
  902.    m.iscontin, m.hascontin, m.i
  903. m.hascontin = .F.
  904. m.done = .F.
  905.  
  906. REPLACE _FOX3SPR.SPRMEMO WITH C_CRLF +;
  907.   "PROCEDURE "+g_procs[m.pnum,1]+ C_CRLF ADDITIVE
  908.  
  909. IF !EMPTY(g_procs[m.pnum,C_MAXPLATFORMS+3])
  910.  
  911.  REPLACE _FOX3SPR.SPRMEMO WITH ;
  912.    "PARAMETERS "+g_procs[m.pnum,C_MAXPLATFORMS+3]+ C_CRLF ADDITIVE
  913.  
  914. ENDIF
  915.  
  916. REPLACE _FOX3SPR.SPRMEMO WITH "DO CASE" + C_CRLF ADDITIVE
  917.  
  918. * Peek ahead and get the parameter statement
  919. FOR m.platnum = 1 TO c_maxplatforms
  920.    IF g_procs[m.pnum,m.platnum+1] < 0
  921.       * There was no procedure for this platform
  922.       LOOP
  923.    ENDIF
  924.    
  925.    REPLACE _FOX3SPR.SPRMEMO WITH "CASE "+"_"+g_platlist[m.platnum]+ C_CRLF ADDITIVE
  926.    m.g_tabchr=C_TAB
  927.    DO putproc WITH m.platnum, m.pnum, m.scrnno
  928.    m.g_tabchr=""
  929. ENDFOR
  930.  
  931. REPLACE _FOX3SPR.SPRMEMO WITH "ENDCASE" + C_CRLF ADDITIVE
  932.  
  933. RETURN
  934.  
  935. *!*****************************************************************************
  936. *!
  937. *!      Procedure: PUTPROC
  938. *!
  939. *!      Called by: EMITBRACKET        (procedure in GENSCRN.PRG)
  940. *!
  941. *!*****************************************************************************
  942. PROCEDURE putproc
  943. *)
  944. *) PUTPROC - Write actual code for procedure procnum in platform platnum
  945. *)
  946. PARAMETER m.platnum, m.procnum, m.scrnno
  947. PRIVATE m.in_rec, m.oldmine, m.done, m.line, m.upline, m.iscontin, m.hascontin, ;
  948.    m.word1, m.word2, m.platnum
  949.  
  950. m.in_rec    = RECNO()
  951. * Store the _MLINE position in the original snippet
  952. m.oldmline  = _MLINE
  953. m.hascontin = .F.       && the previous line was not a continuation line.
  954. LOCATE FOR platform = g_platlist[m.platnum] AND objtype = 1
  955. IF FOUND()
  956.    * go to the PROCEDURE/FUNCTION statement
  957.    _MLINE = g_procs[m.procnum,m.platnum+1]
  958.    * Skip the PROCEDURE line, since we've already output one.
  959.    m.line = MLINE(proccode,1, _MLINE)
  960.    DO killcr WITH m.line
  961.  
  962.    * We are now positioned at the line following the procedure statement.
  963.    * Write until the end of the snippet or the next procedure.
  964.    m.done = .F.
  965.    DO WHILE !m.done
  966.       m.line = MLINE(proccode,1, _MLINE)
  967.       DO killcr WITH m.line
  968.       m.upline = UPPER(ALLTRIM(CHRTRANC(m.line,chr(9),' ')))
  969.       m.iscontin = m.hascontin
  970.       m.hascontin = RIGHT(m.upline,1) = ';'
  971.       IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  972.          m.word1 = wordnum(m.upline, 1)
  973.          IF RIGHT(m.word1,1) = ';'
  974.             m.word1 = LEFT(m.word1,LEN(m.word1)-1)
  975.          ENDIF
  976.  
  977.          DO CASE
  978.          CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  979.             * Stop when we encounter the next snippet
  980.             m.done = .T.
  981.             LOOP
  982.          CASE match(m.word1,"PARAMETERS")
  983.             * Don't output it, but keep scanning for other code
  984.             DO WHILE m.hascontin
  985.                m.line = MLINE(proccode,1, _MLINE)
  986.                DO killcr WITH m.line
  987.                m.upline = UPPER(ALLTRIM(CHRTRANC(m.line,chr(9),' ')))
  988.                m.hascontin = RIGHT(m.upline,1) = ';'
  989.             ENDDO
  990.             LOOP
  991.          ENDCASE
  992.       ENDIF
  993.  
  994.       DO writeline WITH m.line, g_platlist[m.platnum], m.platnum, m.upline, m.scrnno
  995.  
  996.       * Stop if we've run out of snippet
  997.       IF _MLINE >= LEN(proccode)
  998.          m.done = .T.
  999.       ENDIF
  1000.    ENDDO
  1001. ENDIF
  1002.  
  1003. GOTO m.in_rec
  1004. * Restore the _MLINE position in the main snippet we are outputing
  1005. _MLINE = m.oldmline
  1006. RETURN
  1007.  
  1008.  
  1009.  
  1010. *!*****************************************************************************
  1011. *!
  1012. *!      Procedure: UPDPROCARRAY
  1013. *!
  1014. *!*****************************************************************************
  1015. PROCEDURE updprocarray
  1016. *)
  1017. *) UPDPROCARRAY - Pick out the procedures names in the current cleanup snippet and call
  1018. *)                  AddProcName to update the g_procs array.
  1019. *)
  1020. PRIVATE m.i, m.numlines, m.line, m.upline, m.word1, m.word2, m.iscontin, m.hascontin, ;
  1021.    m.lastmline, m.thisproc
  1022.  
  1023. _MLINE = 0
  1024. m.numlines = MEMLINES(proccode)
  1025. m.hascontin = .F.
  1026. FOR m.i = 1 TO m.numlines
  1027.    m.lastmline = _MLINE                && note starting position of this line
  1028.    m.line      = MLINE(proccode,1, _MLINE)
  1029.    DO killcr WITH m.line
  1030.    m.upline    = UPPER(ALLTRIM(m.line))
  1031.    m.iscontin  = m.hascontin
  1032.    m.hascontin = RIGHT(m.upline,1) = ';'
  1033.    IF LEFT(m.upline,1) $ "PF" AND !m.iscontin
  1034.       m.word1 = CHRTRANC(wordnum(m.upline, 1),';','')
  1035.       DO CASE
  1036.       CASE match(m.word1,"PROCEDURE") OR match(m.word1,"FUNCTION")
  1037.          m.word2 = wordnum(m.upline,2)
  1038.          DO addprocname WITH m.word2, platform, m.i, m.lastmline
  1039.          m.lastproc = m.word2
  1040.       CASE match(m.word1,"PARAMETERS")
  1041.          * Associate this parameter statement with the last procedure or function
  1042.          m.thisproc = getprocnum(m.lastproc)
  1043.          IF m.thisproc > 0
  1044.             m.thisparam = ALLTRIM(SUBSTR(m.upline,AT(' ',m.upline)+1))
  1045.             * Deal with continued PARAMETER lines
  1046.             DO WHILE m.hascontin AND m.i <= m.numlines
  1047.                m.lastmline = _MLINE                && note the starting position of this line
  1048.                m.line   = MLINE(proccode,1, _MLINE)
  1049.                DO killcr WITH m.line
  1050.                m.upline = UPPER(ALLTRIM(CHRTRANC(m.line,chr(9),' ')))
  1051.                m.thisparam = ;
  1052.                   m.thisparam + CHR(13)+CHR(10) + m.line
  1053.                m.hascontin = RIGHT(m.upline,1) = ';'
  1054.                m.i = m.i + 1
  1055.             ENDDO
  1056.             * Make sure that this parameter matches any others we've seen for this function
  1057.             DO CASE
  1058.             CASE EMPTY(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  1059.                * First occurrence, or one platform has a parameter statement and another doesn't
  1060.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  1061.             CASE cleanparam(m.thisparam) = cleanparam(g_procs[m.thisproc,C_MAXPLATFORMS+3])
  1062.                * The new one is a superset of the existing one.  Use the longer one.
  1063.                g_procs[m.thisproc,C_MAXPLATFORMS+3] = m.thisparam
  1064.             ENDCASE
  1065.          ENDIF
  1066.       ENDCASE
  1067.    ENDIF
  1068. ENDFOR
  1069. RETURN
  1070.  
  1071.  
  1072.  
  1073. *!*****************************************************************************
  1074. *!
  1075. *!       Function: GETPROCNUM
  1076. *!
  1077. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  1078. *!               : UPDPROCARRAY       (procedure in GENSCRN.PRG)
  1079. *!
  1080. *!*****************************************************************************
  1081. FUNCTION getprocnum
  1082. *)
  1083. *) GETPROCNUM - Return the g_procs array position of the procedure named pname
  1084. *)
  1085. PARAMETER m.pname
  1086. PRIVATE m.i
  1087. FOR m.i = 1 TO g_procnames
  1088.    IF g_procs[m.i,1] == m.pname
  1089.       RETURN m.i
  1090.    ENDIF
  1091. ENDFOR
  1092. RETURN  0
  1093.  
  1094.  
  1095. *!*****************************************************************************
  1096. *!
  1097. *!       Function: CLEANPARAM
  1098. *!
  1099. *!*****************************************************************************
  1100. FUNCTION cleanparam
  1101. *)
  1102. *) CLEANPARAM - Clean up a parameter string so that it may be compared with another one.
  1103. *)              This function replaces tabs with spaces, capitalizes the string, merges
  1104. *)              forces single spacing, and strips out CR/LF characters.
  1105. *)
  1106. PARAMETER m.p, m.cp
  1107. m.cp = UPPER(ALLTRIM(CHRTRANC(m.p,";"+CHR(13)+CHR(10),"")))   && drop CR/LF and continuation chars
  1108. m.cp = CHRTRANC(m.cp,CHR(9),' ')   && tabs to spaces
  1109. DO WHILE AT('  ',m.cp) > 0         && reduce multiple spaces to a single space
  1110.    m.cp = STRTRAN(m.cp,'  ',' ')
  1111. ENDDO
  1112. DO WHILE AT(', ',m.cp) > 0         && drop spaces after commas
  1113.    m.cp = STRTRAN(m.cp,', ',',')
  1114. ENDDO
  1115. RETURN m.cp
  1116.  
  1117. *!*****************************************************************************
  1118. *!
  1119. *!      Procedure: WRITELINE
  1120. *!
  1121. *!      Called by: EMITPROC           (procedure in GENSCRN.PRG)
  1122. *!               : PUTPROC            (procedure in GENSCRN.PRG)
  1123. *!
  1124. *!*****************************************************************************
  1125. PROCEDURE writeline
  1126. *)
  1127. *) WRITELINE - Emit a single line
  1128. *)
  1129. PARAMETER m.line, m.platname, m.platnum, m.upline, m.scrnno
  1130. PRIVATE m.at, m.expr
  1131.  
  1132.    * This code relies upon partial matching (e.g., "*! Comment" will equal "*")
  1133.   DO CASE
  1134.     CASE m.upline = "*"
  1135.       IF !(m.upline = "*!" OR m.upline = "*:")
  1136.         REPLACE _FOX3SPR.SPRMEMO WITH m.g_tabchr + m.line+ C_CRLF ADDITIVE
  1137.       ENDIF
  1138.     CASE m.upline = "#"
  1139.        * don't output a generator directive, but #DEFINES are OK
  1140.        IF LEFT(m.upline,5) = "#DEFI" ;
  1141.             OR LEFT(m.upline,3) = "#IF" ;
  1142.             OR LEFT(m.upline,5) = "#ELSE" ;
  1143.             OR LEFT(m.upline,6) = "#ENDIF"
  1144.         REPLACE _FOX3SPR.SPRMEMO WITH m.g_tabchr + m.line+ C_CRLF ADDITIVE
  1145.        ENDIF
  1146.     OTHERWISE
  1147.        REPLACE _FOX3SPR.SPRMEMO WITH m.g_tabchr + m.line+ C_CRLF ADDITIVE
  1148.   ENDCASE
  1149. RETURN
  1150.  
  1151.  
  1152. *!*****************************************************************************
  1153. *!
  1154. *!       Function: HASCONFLICT
  1155. *!
  1156. *!      Called by: EXTRACTPROCS       (procedure in GENSCRN.PRG)
  1157. *!
  1158. *!*****************************************************************************
  1159. FUNCTION hasconflict
  1160. *)
  1161. *) HASCONFLICT - Is there a name collision for procedure number num?
  1162. *)
  1163. PARAMETER m.num
  1164. PRIVATE m.i, m.cnt
  1165. m.cnt = 0
  1166. FOR m.i = 1 TO c_maxplatforms
  1167.    IF g_procs[m.num,m.i+1] > 0
  1168.       m.cnt = m.cnt +1
  1169.    ENDIF
  1170. ENDFOR
  1171. RETURN IIF(m.cnt > 1,.T.,.F.)
  1172.  
  1173. *!*****************************************************************************
  1174. *!
  1175. *!      Procedure: GETARRANGE
  1176. *!
  1177. *!*****************************************************************************
  1178. PROCEDURE getarrange
  1179. PARAMETER m.astring,m.curplat,m.arrange_flag, m.center_flag, m.row, m.col, m.lscxcenter
  1180. PRIVATE m.j, m.pname, m.entries
  1181. IF !EMPTY(m.astring)
  1182.     m.entries = INT(LEN(m.astring)/26)
  1183.     m.center_flag = m.lscxcenter
  1184.     FOR m.j = 1 TO m.entries
  1185.         m.pname = ALLTRIM(UPPER(SUBSTR(m.astring,(m.j-1)*26+1,8)))
  1186.         m.pname = ALLTRIM(CHRTRANC(m.pname,CHR(0)," "))
  1187.         IF m.pname == m.curplat    && found the right one-platform
  1188.             IF INLIST(UPPER(SUBSTR(m.astring,(m.j-1)*26 + 9,1)),'Y','T')        && is it arranged?
  1189.                 m.arrange_flag = .T.
  1190.                 IF INLIST(UPPER(SUBSTR(m.astring,(m.j-1)*26 + 10,1)),'Y','T')    && is it centered?
  1191.                     m.center_flag = .T.
  1192.                 ELSE
  1193.                     m.center_flag = .F.
  1194.                     m.row = VAL(SUBSTR(m.astring,(m.j-1)*26 + 11,8))
  1195.                     m.col = VAL(SUBSTR(m.astring,(m.j-1)*26 + 19,8))
  1196.                 ENDIF
  1197.             ENDIF
  1198.             EXIT
  1199.         ENDIF
  1200.     NEXT
  1201. ENDIF
  1202.  
  1203. RETURN
  1204.  
  1205. ******************************************************************************
  1206. ******************************************************************************
  1207. * Misc Generic File Utility Routines 
  1208. ******************************************************************************
  1209. ******************************************************************************
  1210.  
  1211. *!*****************************************************************************
  1212. *!       Function: STRIPEXT
  1213. *!*****************************************************************************
  1214. FUNCTION stripext
  1215. *)
  1216. *) STRIPEXT - Strip the extension from a file name.
  1217. *)
  1218. *) Description:
  1219. *) Use the algorithm employed by FoxPRO itself to strip a
  1220. *) file of an extension (if any): Find the rightmost dot in
  1221. *) the filename.  If this dot occurs to the right of a "\"
  1222. *) or ":", then treat everything from the dot rightward
  1223. *) as an extension.  Of course, if we found no dot,
  1224. *) we just hand back the filename unchanged.
  1225. *)
  1226. *) Parameters:
  1227. *) filename - character string representing a file name
  1228. *)
  1229. *) Return value:
  1230. *) The string "filename" with any extension removed
  1231. *)
  1232. PARAMETER m.filename
  1233. PRIVATE m.dotpos, m.terminator
  1234. m.dotpos = RAT(".", m.filename)
  1235. m.terminator = MAX(RAT("\", m.filename), RAT(":", m.filename))
  1236. IF m.dotpos > m.terminator
  1237.    m.filename = LEFT(m.filename, m.dotpos-1)
  1238. ENDIF
  1239. RETURN m.filename
  1240.  
  1241. *!*****************************************************************************
  1242. *!       Function: STRIPPATH
  1243. *!*****************************************************************************
  1244. FUNCTION strippath
  1245. *)
  1246. *) STRIPPATH - Strip the path from a file name.
  1247. *)
  1248. *) Description:
  1249. *) Find positions of backslash in the name of the file.  If there is one
  1250. *) take everything to the right of its position and make it the new file
  1251. *) name.  If there is no slash look for colon.  Again if found, take
  1252. *) everything to the right of it as the new name.  If neither slash
  1253. *) nor colon are found then return the name unchanged.
  1254. *)
  1255. *) Parameters:
  1256. *) filename - character string representing a file name
  1257. *)
  1258. *) Return value:
  1259. *) The string "filename" with any path removed
  1260. *)
  1261. PARAMETER m.filename
  1262. PRIVATE m.slashpos, m.namelen, m.colonpos
  1263. m.slashpos = RAT("\", m.filename)
  1264. IF m.slashpos > 0
  1265.    m.namelen  = LEN(m.filename) - m.slashpos
  1266.    m.filename = RIGHT(m.filename, m.namelen)
  1267. ELSE
  1268.    m.colonpos = RAT(":", m.filename)
  1269.    IF m.colonpos > 0
  1270.       m.namelen  = LEN(m.filename) - m.colonpos
  1271.       m.filename = RIGHT(m.filename, m.namelen)
  1272.    ENDIF
  1273. ENDIF
  1274. RETURN m.filename
  1275.  
  1276. *!*****************************************************************************
  1277. *!       Function: STRIPCR
  1278. *!*****************************************************************************
  1279. FUNCTION stripcr
  1280. *)
  1281. *) STRIPCR - Strip off terminating carriage returns and line feeds
  1282. *)
  1283. PARAMETER m.strg
  1284. * Don't use a CHRTRANC since it's remotely possible that the CR or LF might
  1285. * be in a user's quoted string.
  1286. strg = ALLTRIM(strg)
  1287. i = LEN(strg)
  1288. DO WHILE i >= 0 AND INLIST(SUBSTR(strg,i,1),CHR(13),CHR(10))
  1289.    i = i - 1
  1290. ENDDO
  1291. RETURN LEFT(strg,i)
  1292.  
  1293. *!*****************************************************************************
  1294. *!       Function: ADDBS
  1295. *!*****************************************************************************
  1296. FUNCTION addbs
  1297. *)
  1298. *) ADDBS - Add a backslash unless there is one already there.
  1299. *)
  1300. PARAMETER m.pathname
  1301. PRIVATE m.separator
  1302. m.separator = IIF(_MAC,":","\")
  1303. m.pathname = ALLTRIM(UPPER(m.pathname))
  1304. IF !(RIGHT(m.pathname,1) $ '\:') AND !EMPTY(m.pathname)
  1305.    m.pathname = m.pathname + m.separator
  1306. ENDIF
  1307. RETURN m.pathname
  1308.  
  1309. *!*****************************************************************************
  1310. *!       Function: JUSTFNAME
  1311. *!*****************************************************************************
  1312. FUNCTION justfname
  1313. *)
  1314. *) JUSTFNAME - Return just the filename (i.e., no path) from "filname"
  1315. *)
  1316. PARAMETERS m.filname
  1317.  
  1318. *- use platform specific path (10/28/95 jd)
  1319. LOCAL clocalfname, cdirsep
  1320.  
  1321. cdirsep = IIF(_mac,':','\')
  1322. IF !_mac AND ':' $ filname
  1323.     *- maybe we have a funny filename with extra ":", because of futzing with Mac paths (jd 7/17/96)
  1324.     clocalfname = SUBSTR(m.filname,AT(":",m.filname,OCCURS(":",m.filname)) + 1)
  1325. ELSE
  1326.     clocalfname = m.filname
  1327. ENDIF
  1328.  
  1329. clocalfname = SYS(2027,m.clocalfname )
  1330. IF RAT(m.cdirsep ,m.clocalfname) > 0
  1331.    m.clocalfname = SUBSTR(m.clocalfname,RAT(m.cdirsep,m.clocalfname)+1,255)
  1332. ENDIF
  1333. IF AT(':',m.clocalfname) > 0
  1334.    m.clocalfname = SUBSTR(m.clocalfname,AT(':',m.clocalfname)+1,255)
  1335. ENDIF
  1336. RETURN ALLTRIM(m.clocalfname)
  1337.  
  1338. *!*****************************************************************************
  1339. *!       Function: JUSTSTEM
  1340. *!*****************************************************************************
  1341. FUNCTION juststem
  1342. * Return just the stem name from "filname"
  1343. PARAMETERS m.filname
  1344. *- use platform specific path (10/28/95 jd)
  1345. LOCAL clocalfname, cdirsep
  1346. clocalfname = SYS(2027,m.filname)
  1347. cdirsep = IIF(_mac,':','\')
  1348. IF RAT(m.cdirsep ,m.clocalfname) > 0
  1349.    m.clocalfname = SUBSTR(m.clocalfname,RAT(m.cdirsep,m.clocalfname)+1,255)
  1350. ENDIF
  1351. IF AT(':',m.clocalfname) > 0
  1352.    m.clocalfname = SUBSTR(m.clocalfname,AT(':',m.clocalfname)+1,255)
  1353. ENDIF
  1354. IF AT('.',m.clocalfname) > 0
  1355.    m.clocalfname = SUBSTR(m.clocalfname,1,AT('.',m.clocalfname)-1)
  1356. ENDIF
  1357. RETURN ALLTRIM(UPPER(m.clocalfname))
  1358.  
  1359. *!*****************************************************************************
  1360. *!       Function: JUSTPATH
  1361. *!*****************************************************************************
  1362. FUNCTION justpath
  1363. *)
  1364. *) JUSTPATH - Returns just the pathname.
  1365. *)
  1366. PARAMETERS m.filname
  1367. m.filname = ALLTRIM(UPPER(m.filname))
  1368. *- use platform specific path (10/28/95 jd)
  1369. LOCAL clocalfname, cdirsep
  1370. clocalfname = SYS(2027,m.filname)
  1371. cdirsep = IIF(_mac,':','\')
  1372. IF m.cdirsep $ m.clocalfname 
  1373.    m.clocalfname = SUBSTR(m.clocalfname,1,RAT(m.cdirsep,m.clocalfname ))
  1374.    IF RIGHT(m.filname,1) = m.cdirsep AND LEN(m.filname) > 1 ;
  1375.             AND SUBSTR(m.clocalfname,LEN(m.clocalfname)-1,1) <> ':'
  1376.          clocalfname= SUBSTR(m.clocalfname,1,LEN(m.clocalfname)-1)
  1377.    ENDIF
  1378.    RETURN m.clocalfname
  1379. ELSE
  1380.    RETURN ''
  1381. ENDIF
  1382.  
  1383. *!*****************************************************************************
  1384. *!       Function: JUSTEXT
  1385. *!*****************************************************************************
  1386. FUNCTION justext
  1387. * Return just the extension from "filname"
  1388. PARAMETERS m.filname
  1389. PRIVATE m.ext
  1390. filname = justfname(m.filname)   && prevents problems with ..\ paths
  1391. m.ext = ""
  1392. IF AT('.',m.filname) > 0
  1393.    m.ext = SUBSTR(m.filname,AT('.',m.filname)+1,3)
  1394. ENDIF
  1395. RETURN UPPER(m.ext)
  1396.  
  1397. *!*****************************************************************************
  1398. *!       Function: JustDrive
  1399. *!*****************************************************************************
  1400. FUNCTION JustDrive
  1401. *- Return just the drive from "filname"
  1402. PARAMETERS m.filname
  1403. RETURN LEFT(m.filname,IIF(":" $ m.filname,AT(":",m.filname) - 1,""))
  1404.  
  1405. *!*****************************************************************************
  1406. *!      Procedure: PARTIALFNAME
  1407. *!*****************************************************************************
  1408. FUNCTION partialfname
  1409. PARAMETER m.filname, m.fillen
  1410. * Return a filname no longer than m.fillen characters.  Take some chars
  1411. * out of the middle if necessary.  No matter what m.fillen is, this function
  1412. * always returns at least the file stem and extension.
  1413. PRIVATE m.bname, m.elipse, m.remain,m.g_pathsep
  1414. IF _MAC
  1415.     m.g_pathsep = ":"
  1416. ELSE
  1417.     m.g_pathsep = "\"
  1418. ENDIF
  1419.  
  1420. m.elipse = "..." + m.g_pathsep
  1421. IF _MAC
  1422.     m.bname = SUBSTR(m.filname, RAT(":",m.filname)+1)
  1423. ELSE
  1424.     m.bname = justfname(m.filname)
  1425. ENDIF
  1426. DO CASE
  1427. CASE LEN(m.filname) <= m.fillen
  1428.    m.retstr = m.filname
  1429. CASE LEN(m.bname) + LEN(m.elipse) >= m.fillen
  1430.    m.retstr = m.bname
  1431. OTHERWISE
  1432.    m.remain = MAX(m.fillen - LEN(m.bname) - LEN(m.elipse), 0)
  1433.    IF _MAC
  1434.        m.retstr = LEFT(SUBSTR(m.filname,1,RAT(":",m.filname)-1),m.remain) ;
  1435.             +m.elipse+m.bname
  1436.    ELSE
  1437.          m.retstr = LEFT(justpath(m.filname),m.remain)+m.elipse+m.bname
  1438.    ENDIF
  1439. ENDCASE
  1440. RETURN m.retstr
  1441.  
  1442. *!*****************************************************************************
  1443. *!       Function: FORCEEXT
  1444. *!*****************************************************************************
  1445. FUNCTION forceext
  1446. *)
  1447. *) FORCEEXT - Force filename to have a particular extension.
  1448. *)
  1449. PARAMETERS m.filname,m.ext
  1450. PRIVATE m.ext
  1451. IF SUBSTR(m.ext,1,1) = "."
  1452.    m.ext = SUBSTR(m.ext,2,3)
  1453. ENDIF
  1454.  
  1455. m.pname = justpath(m.filname)
  1456. m.filname = justfname(UPPER(ALLTRIM(m.filname)))
  1457. IF AT('.',m.filname) > 0
  1458.    m.filname = SUBSTR(m.filname,1,AT('.',m.filname)-1) + '.' + m.ext
  1459. ELSE
  1460.    m.filname = m.filname + '.' + m.ext
  1461. ENDIF
  1462. RETURN addbs(m.pname) + m.filname
  1463.  
  1464. ********************
  1465. procedure CPCodes
  1466. ********************
  1467.     * This procedure initializes a two-column array containing code pages
  1468.     * and their corresponding DBF Byte identifier.
  1469.  
  1470.     parameters m.wzaCPCodes
  1471.  
  1472.     dimension wzaCPCodes[20,2]
  1473.  
  1474.     wzaCPCodes[ 1,1] = 437        && US MS-DOS
  1475.     wzaCPCodes[ 1,2] = 1
  1476.     wzaCPCodes[ 2,1] = 850        && International MS-DOS
  1477.     wzaCPCodes[ 2,2] = 2
  1478.     wzaCPCodes[ 3,1] = 1252        && Windows ANSI
  1479.     wzaCPCodes[ 3,2] = 3
  1480.     wzaCPCodes[ 4,1] = 10000    && Standard Macintosh
  1481.     wzaCPCodes[ 4,2] = 4
  1482.     wzaCPCodes[ 5,1] = 852        && Eastern European MS-DOS
  1483.     wzaCPCodes[ 5,2] = 100
  1484.     wzaCPCodes[ 6,1] = 866        && Russian MS-DOS
  1485.     wzaCPCodes[ 6,2] = 101
  1486.     wzaCPCodes[ 7,1] = 865        && Nordic MS-DOS
  1487.     wzaCPCodes[ 7,2] = 102
  1488.     wzaCPCodes[ 8,1] = 861        && Icelandic MS-DOS
  1489.     wzaCPCodes[ 8,2] = 103
  1490.     wzaCPCodes[ 9,1] = 895        && Kamenicky (Czech) MS-DOS
  1491.     wzaCPCodes[ 9,2] = 104
  1492.     wzaCPCodes[10,1] = 620        && Mazovia (Polish) MS-DOS
  1493.     wzaCPCodes[10,2] = 105
  1494.     wzaCPCodes[11,1] = 737        && Greek MS-DOS
  1495.     wzaCPCodes[11,2] = 106
  1496.     wzaCPCodes[12,1] = 857        && Turkish MS-DOS
  1497.     wzaCPCodes[12,2] = 107
  1498.     wzaCPCodes[13,1] = 10007    && Russian Macintosh
  1499.     wzaCPCodes[13,2] = 150
  1500.     wzaCPCodes[14,1] = 10029    && Eastern European Macintosh
  1501.     wzaCPCodes[14,2] = 151
  1502.     wzaCPCodes[15,1] = 10006    && Greek Macintosh
  1503.     wzaCPCodes[15,2] = 152
  1504.     wzaCPCodes[16,1] = 1250        && Eastern European Windows
  1505.     wzaCPCodes[16,2] = 200
  1506.     wzaCPCodes[17,1] = 1251        && Russian Windows
  1507.     wzaCPCodes[17,2] = 201
  1508.     wzaCPCodes[18,1] = 1253        && Greek Windows
  1509.     wzaCPCodes[18,2] = 203
  1510.     wzaCPCodes[19,1] = 1254        && Turkish Windows
  1511.     wzaCPCodes[19,2] = 202
  1512.     wzaCPCodes[20,1] = 0        && Not tagged
  1513.     wzaCPCodes[20,2] = 0
  1514.  
  1515. ENDPROC
  1516.  
  1517. ********************
  1518. procedure CPTag
  1519. ********************
  1520.     * This procedure tags the specified table with the specified code page.
  1521.     * This procedure is designed to be called after having opened a table and
  1522.     * checked the CPDBF() value. It does not verify that the file is a DBF.
  1523.  
  1524.     parameters m.wzsFName, m.wziCodePage
  1525.  
  1526.     #DEFINE C_NOFILE    20    && Invalid code page
  1527.     #DEFINE C_BADCODEPG    21    && Invalid code page
  1528.     #DEFINE C_NOOPEN    22    && File could not be opened
  1529.     private m.wziHandle, m.wzaCPCodes, m.wziDBFByte, m.wzi
  1530.  
  1531.     dimension wzaCPCodes[1]
  1532.     do CPCodes with wzaCPCodes
  1533.  
  1534.     m.wziDBFByte=-1
  1535.     for m.wzi=1 to alen(wzaCPCodes,1)
  1536.         if m.wziCodePage=wzaCPCodes[m.wzi,1]
  1537.             m.wziDBFByte=wzaCPCodes[m.wzi,2]
  1538.             exit
  1539.         endif
  1540.     endfor
  1541.     if m.wziDBFByte=-1 && Invalid code page
  1542.         =MESSAGEBOX(STRTRAN(E_BADCODEPAGE_LOC,"@1",ALLT(STR(m.wziCodePage)),1))
  1543.         return .f.
  1544.     else
  1545.         if !file(m.wzsFName) && File does not exist
  1546.             =MESSAGEBOX(STRTRAN(E_FILENOEXIST_LOC,"@1",m.wzsFName,1))
  1547.             return .f.
  1548.         else
  1549.             m.wziHandle=FOPEN(m.wzsFName,2)
  1550.             if !m.wziHandle=-1
  1551.                 * Poke the codepage id into byte 29
  1552.                 =fseek(m.wziHandle,29)
  1553.                 =fwrite(m.wziHandle,chr(m.wziDBFByte))
  1554.                 =fclose(m.wziHandle)
  1555.             else && File could not be opened
  1556.                 =MESSAGEBOX(E_NOOPEN_LOC + m.wzsFName)
  1557.                 return .f.
  1558.             endif
  1559.         endif
  1560.     endif
  1561.  
  1562. ENDFUNC
  1563.  
  1564.     
  1565. *------------------------------------
  1566. PROCEDURE EscHand
  1567. *------------------------------------
  1568. RETURN
  1569.  
  1570. *------------------------------------
  1571. PROCEDURE Readable
  1572. *------------------------------------
  1573. *- Check to see if the file is readable
  1574.  
  1575.     PARAMETER cFile
  1576.  
  1577.     LOCAL m.nFileReady
  1578.  
  1579.     m.nFileReady = FOPEN(cFile)
  1580.     IF m.nFileReady = -1
  1581.         RETURN .F.
  1582.     ELSE
  1583.         =FCLOSE(m.nFileReady)
  1584.         RETURN .T.
  1585.     ENDIF
  1586.  
  1587. ENDPROC
  1588.  
  1589.  
  1590. *------------------------------------
  1591. PROCEDURE TmpAlias
  1592. *------------------------------------
  1593. * Returns generated name for use as an alias.
  1594. PRIVATE m.wzsAlias
  1595. m.wzsAlias=SYS(2015)
  1596. DO WHILE USED(m.wzsAlias)
  1597.     m.wzsAlias=SYS(2015)
  1598. ENDDO
  1599. RETURN m.wzsAlias
  1600.  
  1601.  
  1602. *------------------------------------
  1603. procedure UpdPaths
  1604. *------------------------------------
  1605. PARAMETERS m.wzsOldName
  1606.  
  1607. PRIVATE m.wzsJustPath, m.wzsPath, m.wzsTName
  1608. m.wzsPath=SET('path')
  1609. SET PATH TO
  1610.  
  1611. m.wzsJustPath=addbs(upper(justpath(SYS(2027,m.wzsOldName))))
  1612.  
  1613. SCAN FOR !UPPER(type)=='FPC'
  1614.     IF m.wzsJustPath$SYS(2027,upper(path))
  1615.         m.wzsTName=STRTRAN(SYS(2027,upper(path)),m.wzsJustPath,'',1,1)
  1616.         IF file(addbs(justpath(SYS(2027,dbf())))+m.wzsTName)
  1617.             REPLACE path WITH upper(addbs(justpath(SYS(2027,dbf())))+m.wzsTName)
  1618.             LOOP
  1619.         ENDIF
  1620.         IF JUSTDRIVE(SYS(2027,upper(path)))==JUSTDRIVE(m.wzsJustPath)
  1621.             m.wzsTName=STRTRAN(SYS(2027,UPPER(path)),JUSTDRIVE(m.wzsJustPath),'',1,1)
  1622.             IF FILE(JUSTDRIVE(SYS(2027,dbf()))+m.wzsTName)
  1623.                 REPLACE path WITH upper(justdrive(SYS(2027,dbf()))+m.wzsTName)
  1624.             ENDIF
  1625.         ENDIF
  1626.     ENDIF
  1627. ENDSCAN
  1628.  
  1629. LOCATE FOR UPPER(type)=='FPC'
  1630. REPLACE path WITH DBF()
  1631.  
  1632. SET PATH TO (m.wzsPath)
  1633. RETURN
  1634.  
  1635. *------------------------------------
  1636. procedure DBTable
  1637. *------------------------------------
  1638. * This procedure returns .t. if the specified file has a dBASE III or IV
  1639. * memo field that will need to be converted.
  1640.  
  1641. parameters m.wzsFName
  1642.  
  1643. if !file(m.wzsFName)
  1644.     return .f.
  1645. endif
  1646.  
  1647. wzsFName = SYS(2027,wzsFName)
  1648.  
  1649. private m.wziTypeByte, m.wziHandle
  1650. m.wziHandle=FOPEN(m.wzsFName)
  1651. if m.wziHandle=-1
  1652.     =MESSAGEBOX(E_NOOPEN_LOC + m.wzsFName)
  1653.     return .f.
  1654. endif
  1655. m.wziTypeByte=asc(fread(m.wziHandle,1))
  1656. if !fclose(m.wziHandle)
  1657.     =MESSAGEBOX(E_NOCLOSE_LOC + m.wzsFName)
  1658. endif
  1659.  
  1660. * 0x83 (131) FoxBASE+/dBASE III PLUS, with memo
  1661. * 0x8B (139) dBASE IV, with memo
  1662. if m.wziTypeByte=131 .or. m.wziTypeByte=139
  1663.     return .t.
  1664. else
  1665.     return .f.
  1666. endif
  1667.  
  1668. *------------------------------------
  1669. procedure FileExt
  1670. *------------------------------------
  1671. * This procedure returns the FoxPro extension based on the
  1672. * type of file.
  1673. parameters m.wzsType, m.wzsMethod
  1674. do case
  1675. case m.wzsType='TABLE'
  1676.     return 'dbf'
  1677. case m.wzsType='QUERY'
  1678.     if m.wzsMethod='DESIGN'
  1679.         return 'qpr'
  1680.     else
  1681.         return 'fpq'
  1682.     endif
  1683. case m.wzsType='FORM'
  1684.     return 'scx'
  1685. case m.wzsType='REPORT'
  1686.     return 'frx'
  1687. case m.wzsType='LABEL'
  1688.     return 'lbx'
  1689. case m.wzsType='PROGRAM'
  1690.     return 'prg'
  1691. case m.wzsType='CATALOG'
  1692.     return 'fpc'
  1693. endcase
  1694.  
  1695. *----------------------------------
  1696. FUNCTION CvtLine
  1697. *----------------------------------
  1698.     *-      Convert DOS char-type lines to line objects
  1699.     *-
  1700.     *-        Assume report or screen is open exclusive as DBF, with alias newfile
  1701.     *-        and is positioned on record with text field
  1702.     PARAMETER avline
  1703.  
  1704.     #DEFINE K_LOWLINE        179
  1705.     #DEFINE K_HILINE        218
  1706.     #DEFINE K_HORZLN1        CHR(196)
  1707.     #DEFINE K_VERTLN1        CHR(179)
  1708.  
  1709.     #DEFINE K_ULCORN1        CHR(218)
  1710.     #DEFINE K_URCORN1        CHR(191)
  1711.     #DEFINE K_LLCORN1        CHR(192)
  1712.     #DEFINE K_LRCORN1        CHR(217)
  1713.  
  1714.     #DEFINE K_CROSS1        CHR(197)
  1715.     #DEFINE K_LCROSS1        CHR(195)
  1716.     #DEFINE K_RCROSS1        CHR(180)
  1717.     #DEFINE K_TCROSS1        CHR(194)
  1718.     #DEFINE K_BCROSS1        CHR(193)
  1719.  
  1720.     #DEFINE K_RV1H2            CHR(181)    && Right side, single vertical, double horizontal
  1721.     #DEFINE K_LV1H2            CHR(198)    && Left side, single vertical, double horizontal
  1722.     #DEFINE K_CV1H2            CHR(216)    && Cross, single vertical, double horizontal
  1723.  
  1724.     *- mixed single/double
  1725.     #DEFINE K_V1H2            CHR(213) + CHR(209) + CHR(184) + CHR(198) + CHR(216) + CHR(181) + CHR(212) + CHR(207) + CHR(190)
  1726.     #DEFINE K_V2H1            CHR(214) + CHR(210) + CHR(183) + CHR(199) + CHR(215) + CHR(182) + CHR(211) + CHR(208) + CHR(189)
  1727.  
  1728.     #DEFINE K_HORZSET1        K_HORZLN1 + K_ULCORN1 + K_URCORN1 + K_LLCORN1 + K_LRCORN1 + K_CROSS1 + K_LCROSS1 + K_RCROSS1 + K_TCROSS1 + K_BCROSS1 + K_V2H1
  1729.     #DEFINE K_VERTSET1        K_VERTLN1 + K_ULCORN1 + K_URCORN1 + K_LLCORN1 + K_LRCORN1 + K_CROSS1 + K_LCROSS1 + K_RCROSS1 + K_TCROSS1 + K_BCROSS1 + K_V1H2
  1730.     *----------------------------------
  1731.     #DEFINE K_HORZLN2        CHR(205)
  1732.     #DEFINE K_VERTLN2        CHR(186)
  1733.  
  1734.     #DEFINE K_ULCORN2        CHR(201)
  1735.     #DEFINE K_URCORN2        CHR(187)
  1736.     #DEFINE K_LLCORN2        CHR(200)
  1737.     #DEFINE K_LRCORN2        CHR(188)
  1738.  
  1739.     #DEFINE K_CROSS2        CHR(206)
  1740.     #DEFINE K_LCROSS2        CHR(204)
  1741.     #DEFINE K_RCROSS2        CHR(185)
  1742.     #DEFINE K_TCROSS2        CHR(203)
  1743.     #DEFINE K_BCROSS2        CHR(202)
  1744.  
  1745.     #DEFINE K_HORZSET2        K_HORZLN2 + K_ULCORN2 + K_URCORN2 + K_LLCORN2 + K_LRCORN2 + K_CROSS2 + K_LCROSS2 + K_RCROSS2 + K_TCROSS2 + K_BCROSS2 + K_V1H2
  1746.     #DEFINE K_VERTSET2        K_VERTLN2 + K_ULCORN2 + K_URCORN2 + K_LLCORN2 + K_LRCORN2 + K_CROSS2 + K_LCROSS2 + K_RCROSS2 + K_TCROSS2 + K_BCROSS2 + K_V2H1
  1747.  
  1748.     LOCAL lhsingle, lhdouble, lvsingle, lvdouble, nlen, nstartpos, nvpos, nhpos, nctr,;
  1749.         ncurrec, ccolorpr
  1750.         
  1751.     *- see if special chars are in the text field
  1752.     m.nlen = LEN(newfile.expr)
  1753.     m.nstartpos = -1
  1754.     STORE .F. TO m.lhsingle, m.lhdouble
  1755.     FOR m.nctr = 2 TO m.nlen
  1756.         m.cchar = SUBS(newfile.expr,m.nctr,1)
  1757.         m.nascval = ASC(m.cchar)
  1758.         IF m.cchar $ K_HORZSET1 OR m.cchar $ K_HORZSET2
  1759.             *- horizontal line
  1760.             *- see if run of the little buggers
  1761.             IF m.nstartpos = -1
  1762.                 *- remember line characteristics
  1763.                 IF m.cchar $ K_HORZSET1
  1764.                     m.lhsingle = .T.
  1765.                     m.lhdouble = .F.
  1766.                 ENDIF
  1767.                 IF m.cchar $ K_HORZSET2
  1768.                     m.lhsingle = .F.
  1769.                     m.lhdouble = .T.
  1770.                 ENDIF
  1771.                 m.nstartpos = m.nctr
  1772.             ENDIF
  1773.         ELSE
  1774.             IF m.nstartpos <> -1
  1775.                 *- started a run, and it has ended
  1776.                 *- remember current coords
  1777.                 m.nvpos = newfile.vpos
  1778.                 m.nhpos = newfile.hpos
  1779.                 IF m.filetype = dbiv_scr_type
  1780.                     m.ccolorpr = newfile.colorpair
  1781.                 ENDIF
  1782.                 m.ncurrec = RECNO()
  1783.                 *- remove line chars from text field
  1784.                 IF m.nctr - m.nstartpos - 1 = m.nlen
  1785.                     *- entire text field is a line, so use this record
  1786.                 ELSE
  1787.                     REPLACE newfile.expr WITH LEFT(newfile.expr,m.nstartpos - 1) + ;
  1788.                             SPACE(m.nctr - m.nstartpos) + ;
  1789.                             SUBS(newfile.expr,m.nctr)
  1790.                     *- add record to report/screen
  1791.                     APPEND BLANK
  1792.                 ENDIF
  1793.                 REPLACE newfile.objtype WITH 7,;
  1794.                     newfile.objcode WITH IIF(m.lhsingle,4,5),;
  1795.                     newfile.vpos WITH m.nvpos,;
  1796.                     newfile.hpos WITH m.nhpos + m.nstartpos - 2,;
  1797.                     newfile.height WITH 1,;
  1798.                     newfile.width WITH m.nctr - m.nstartpos
  1799.                 IF m.filetype = dbiv_scr_type
  1800.                     REPLACE newfile.colorpair WITH m.ccolorpr
  1801.                 ENDIF
  1802.                 *- reset start pos
  1803.                 m.nstartpos = -1
  1804.                 *- return to the record in question
  1805.                 GO m.ncurrec
  1806.             ENDIF
  1807.         ENDIF
  1808.         STORE .F. TO m.lvsingle, m.lvdouble
  1809.         IF m.cchar $ K_VERTSET1
  1810.             m.lvsingle = .T.
  1811.         ENDIF
  1812.         IF m.cchar $ K_VERTSET2
  1813.             m.lvdouble = .T.
  1814.         ENDIF
  1815.         IF m.lvsingle OR m.lvdouble
  1816.             *- vertical line
  1817.             IF m.filetype = dbiv_scr_type
  1818.                 m.ccolorpr = newfile.colorpair
  1819.             ENDIF
  1820.             m.nhpos = newfile.hpos + m.nctr - 1
  1821.             IF avline[m.nhpos,1] = -1
  1822.                 *- new vertical line
  1823.                 avline[m.nhpos,1] = newfile.vpos
  1824.                 avline[m.nhpos,2] = 1
  1825.                 avline[m.nhpos,4] = m.lvsingle
  1826.                 IF m.filetype = dbiv_scr_type
  1827.                     avline[m.nhpos,3] = m.ccolorpr
  1828.                 ENDIF
  1829.             ELSE
  1830.                 avline[m.nhpos,2] = avline[m.nhpos,2] + 1
  1831.             ENDIF
  1832.             IF m.nlen = 3
  1833.                 *- entire text field is a line, so delete this record
  1834.                 DELETE
  1835.             ELSE
  1836.                 *- replace vertical line with space
  1837.                 REPLACE newfile.expr WITH LEFT(newfile.expr,m.nctr - 1) + ;
  1838.                     SPACE(1) + ;
  1839.                     SUBS(newfile.expr,m.nctr + 1)
  1840.             ENDIF
  1841.         ELSE
  1842.             *- check if vertical line ended
  1843.             m.nhpos = newfile.hpos + m.nctr - 1
  1844.             IF avline[m.nhpos,1] <> -1
  1845.                 *- remember current coords
  1846.                 m.ncurrec = RECNO()
  1847.                 *- add record
  1848.                 APPEND BLANK
  1849.                 REPLACE newfile.objtype WITH 7,;
  1850.                     newfile.objcode WITH IIF(avline[m.nhpos,4],4,5),;
  1851.                     newfile.vpos WITH avline[m.nhpos,1],;
  1852.                     newfile.hpos WITH m.nhpos - 1,;
  1853.                     newfile.height WITH avline[m.nhpos,2],;
  1854.                     newfile.width WITH 1 
  1855.                 IF m.filetype = dbiv_scr_type
  1856.                     REPLACE newfile.colorpair WITH avline[m.nhpos,3]
  1857.                 ENDIF
  1858.                 *- return to the record in question
  1859.                 GO m.ncurrec
  1860.                 *- reset array
  1861.                 avline[m.nhpos,1] = -1
  1862.                 avline[m.nhpos,2] = -1
  1863.                 avline[m.nhpos,3] = -1
  1864.                 avline[m.nhpos,4] = -1
  1865.             ENDIF  && end of vertical line
  1866.         ENDIF
  1867.     NEXT
  1868.     *- trim off unnecessary spaces?
  1869.     m.nleadspac = LEN(SUBS(newfile.expr,2)) - LEN(LTRIM(SUBS(newfile.expr,2)))
  1870.     IF m.nleadspac > 0
  1871.         REPLACE newfile.expr WITH '"' + SUBS(newfile.expr,m.nleadspac + 2),;
  1872.             newfile.hpos WITH newfile.hpos + m.nleadspac,;
  1873.             newfile.width WITH MAX(LEN(newfile.expr) - 2,0)
  1874.     ENDIF
  1875.     m.ntrailspac = LEN(newfile.expr) - 1 - LEN(TRIM(LEFT(newfile.expr,LEN(newfile.expr) - 1)))
  1876.     IF m.ntrailspac > 0
  1877.         REPLACE newfile.expr WITH LEFT(newfile.expr,LEN(newfile.expr) - 1 - m.ntrailspac) + '"',;
  1878.             newfile.width WITH MAX(LEN(newfile.expr) - 2,0)
  1879.     ENDIF
  1880.     *- remove invalid records
  1881.     DELETE ALL FOR newfile.objtype = 5 AND newfile.expr = '""'
  1882.     RETURN
  1883.  
  1884. ENDFUNC
  1885.  
  1886. *----------------------------------
  1887. PROCEDURE FixVert
  1888. *----------------------------------
  1889. *- Check for vertical lines that haven't been added to form
  1890.     PARAMETER avline
  1891.  
  1892.     LOCAL m.nctr
  1893.  
  1894.     FOR m.nctr = 1 TO ALEN(avline,1)
  1895.         IF avline[m.nctr,1] <> -1
  1896.             *- add record
  1897.             APPEND BLANK
  1898.             REPLACE newfile.objtype WITH 7,;
  1899.                 newfile.objcode WITH IIF(avline[m.nctr,4],4,5),;
  1900.                 newfile.vpos WITH avline[m.nctr,1],;
  1901.                 newfile.hpos WITH m.nctr,;
  1902.                 newfile.height WITH avline[m.nctr,2],;
  1903.                 newfile.width WITH 1,;
  1904.                 newfile.uniqueid WITH SYS(2015),;
  1905.                 newfile.platform WITH "DOS" 
  1906.             IF m.filetype = dbiv_scr_type
  1907.                 REPLACE newfile.colorpair WITH avline[m.nctr,3]
  1908.             ENDIF
  1909.         ENDIF
  1910.     NEXT
  1911.     *- pack to get rid of deleted vertical line records
  1912.     PACK
  1913.     RETURN
  1914.     
  1915. ENDPROC        && FixVert
  1916.  
  1917. *----------------------------------
  1918. PROCEDURE GoodName
  1919. *----------------------------------
  1920.     *- Make a legal alias out of parm.
  1921.     PARAMETERS m.wzsAlias
  1922.     PRIVATE m.i,m.c,m.retval
  1923.     IF '\' $ m.wzsAlias
  1924.         m.wzsAlias = JustStem(m.wzsAlias)
  1925.     ENDIF
  1926.     IF m.wzsAlias # '_'  AND !ISALPHA(m.wzsAlias)
  1927.         m.wzsAlias = '_' + m.wzsAlias
  1928.     ENDIF
  1929.     *- reworked code to prevent err if name is longer than 10 (jd 5/6/94)
  1930.     m.retval=""
  1931.     FOR m.i=1 TO MIN(LEN(m.wzsAlias),10)    &&max len of alias
  1932.         m.c = SUBSTR(m.wzsAlias,m.i,1)
  1933.         IF !ISALPHA(m.c) AND m.c # '_' AND !ISDIGIT(m.c)
  1934.             m.retval = m.retval + "_"
  1935.         ELSE
  1936.             m.retval = m.retval + m.c
  1937.         ENDIF
  1938.     ENDFOR
  1939.     RETURN m.retval
  1940.     
  1941. ENDPROC        && GoodName
  1942.  
  1943. *----------------------------------
  1944. FUNCTION EvalData
  1945. *----------------------------------
  1946.     PARAMETER m.cData,m.cDataType
  1947.     DO CASE
  1948.         CASE m.cDataType= 'C'
  1949.             RETURN m.cData
  1950.         CASE m.cDataType= 'N'
  1951.             RETURN VAL(m.cData)
  1952.         CASE m.cDataType= 'D'
  1953.             RETURN CTOD(m.cData)
  1954.         CASE m.cDataType= 'L'
  1955.             m.ctempexpr = m.cData
  1956.             RETURN EVALUATE(ctempexpr)
  1957.         CASE  m.cDataType= 'A'
  1958.             *- handle arrays differently
  1959.             RETURN ''
  1960.         OTHERWISE
  1961.             *- ???? unknown? undefined??
  1962.             RETURN ''
  1963.     ENDCASE
  1964.     RETURN ''
  1965. ENDFUNC        && EvalData
  1966.  
  1967. *----------------------------------
  1968. FUNCTION StripQuote
  1969. *----------------------------------
  1970.     *- strip off quotes of string
  1971.     PARAMETER cString
  1972.  
  1973.     LOCAL  cQuote
  1974.  
  1975.     cQuote = LEFT(cString,1)
  1976.     IF m.cQuote $ ["'] + "]"
  1977.         cString = STRTRAN(cString,cQuote,"")
  1978.         IF cQuote = "["
  1979.             cString = STRTRAN(cString,"]","")
  1980.         ENDIF
  1981.     ENDIF
  1982.     RETURN cString
  1983.  
  1984. ENDFUNC        && StripQuote
  1985.  
  1986. *----------------------------------
  1987. FUNCTION StripParen
  1988. *----------------------------------
  1989.     *- strip out any text within parens
  1990.     PARAMETER cText, cLParen, cRParen
  1991.  
  1992.     IF cLParen $ cText AND !(cRParen $ cText)
  1993.         *- no matching rparen
  1994.         cText = LEFT(cText,AT(cLParen,cText) - 1)
  1995.     ENDIF
  1996.  
  1997.     DO WHILE cLParen $ cText
  1998.         cText = LEFT(cText,AT(cLParen,cText) - 1) + ;
  1999.             IIF(AT(cRParen,cText) = LEN(cText),"",SUBS(cText,RAT(cRParen,cText) + 1))
  2000.     ENDDO
  2001.     *- strip out lingering right parens
  2002.     m.cText = STRTRAN(m.cText,cRParen,"")
  2003.     RETURN m.cText
  2004. ENDFUNC        && StripParen
  2005.  
  2006. *----------------------------------
  2007. FUNCTION GoodName
  2008. *----------------------------------
  2009.     *- convert a string to a valid VFP object name
  2010.     PARAMETER cText
  2011.  
  2012.     LOCAL j
  2013.  
  2014.     IF !(ISALPHA(SUBS(m.cText,1,1)) OR SUBS(m.cText,1,1) == "_")
  2015.         m.cText = STUFF(m.cText,1,1,"_")
  2016.     ENDIF
  2017.     FOR m.j = 2 TO LEN(m.cText)
  2018.         IF !(ISALPHA(SUBS(m.cText,j,1)) OR ;
  2019.             ISDIGIT(SUBS(m.cText,j,1)) OR ;
  2020.             SUBS(m.cText,j,1) == "_")
  2021.             m.cText = STUFF(m.cText,j,1,"_")
  2022.         ENDIF
  2023.     NEXT
  2024.     RETURN m.cText
  2025. ENDFUNC
  2026.  
  2027. *----------------------------------
  2028. FUNCTION IsDir
  2029. *----------------------------------
  2030.     *- test if a directory exists
  2031.     PARAMETER cDir
  2032.  
  2033.     LOCAL aDirArry, iDirCt
  2034.  
  2035.     DIMENSION aDirArry[1]
  2036.  
  2037.     iDirCt = ADIR(aDirArry,AddBS(cDir) + "*.*", "D")
  2038.  
  2039.     RETURN (m.iDirCt > 0)
  2040.  
  2041. ENDFUNC
  2042.  
  2043. *----------------------------------
  2044. PROCEDURE EscHandler
  2045. *----------------------------------
  2046.  
  2047.     IF MESSAGEBOX(C_ESCAPE_LOC,MB_YESNO + 256) = IDYES
  2048.         IF TYPE("gOPJX") = 'O'
  2049.             *- it's an object
  2050.             gOPJX.Error(0)
  2051.         ELSE
  2052.             *- problem -- escape has been set, but no object (should be impossible)
  2053.             CLOSE ALL
  2054.             RETURN TO MASTER
  2055.         ENDIF
  2056.     ENDIF
  2057.  
  2058. ENDPROC
  2059.  
  2060. *----------------------------------
  2061. PROCEDURE FatalErr
  2062. *----------------------------------
  2063.     *-  ON ERROR is set to this in the Error Method
  2064.     =MESSAGEBOX(E_FATAL_LOC)
  2065.     gError = .T.
  2066.     RETURN TO MASTER
  2067.  
  2068. ENDPROC
  2069.  
  2070. ********************
  2071.  PROCEDURE autoname
  2072. ********************
  2073.     * This procedure generates an automatic name based on a filename.
  2074.     
  2075.     PARAMETERS m.wzsbasename, m.wzsextension, m.wzlwithmemo
  2076.     PRIVATE m.wzi, m.wzspath, m.wzsstem, m.wziwidth
  2077.     
  2078.     m.wzspath=addbs(justpath(SYS(2027,m.wzsbasename)))
  2079.     m.wzsstem=juststem(m.wzsbasename)
  2080.     m.wzi=1
  2081.     DO WHILE .T.
  2082.         DO CASE
  2083.             CASE _DOS .OR. _WINDOWS
  2084.                 m.wziwidth=8-(LEN(ALLTRIM(STR(m.wzi)))+1)
  2085.                 m.wzsautoname=UPPER(m.wzspath+LEFT(m.wzsstem,m.wziwidth)+'_'+ ;
  2086.                     ALLTRIM(STR(m.wzi))+'.'+m.wzsextension)
  2087.             CASE _MAC
  2088.                 m.wziwidth=27-(LEN(ALLTRIM(STR(m.wzi)))+1)  && max stem for Mac is 27 (27 + .xxx = 31)
  2089.                 m.wzsautoname=UPPER(m.wzspath+LEFT(m.wzsstem,m.wziwidth)+'_'+ ;
  2090.                     ALLTRIM(STR(m.wzi))+'.'+m.wzsextension)
  2091.             OTHERWISE
  2092.                 && work needed here for _unix
  2093.                 RETURN ""
  2094.                 *-DO errhand WITH LINENO(), 0, wzatext[175], ''
  2095.         ENDCASE
  2096.         IF FILE(m.wzsautoname)
  2097.             m.wzi=m.wzi+1
  2098.         ELSE
  2099.             DO CASE
  2100.                 CASE UPPER(m.wzsextension)='SCX'
  2101.                     IF FILE(forceext(m.wzsautoname,'SCT'))
  2102.                         m.wzi=m.wzi+1
  2103.                     ELSE
  2104.                         EXIT
  2105.                     ENDIF
  2106.                 CASE UPPER(m.wzsextension)='FRX'
  2107.                     IF FILE(forceext(m.wzsautoname,'FRT'))
  2108.                         m.wzi=m.wzi+1
  2109.                     ELSE
  2110.                         EXIT
  2111.                     ENDIF
  2112.                 CASE m.wzlwithmemo
  2113.                     IF FILE(forceext(m.wzsautoname,'FPT'))
  2114.                         m.wzi=m.wzi+1
  2115.                     ELSE
  2116.                         EXIT
  2117.                     ENDIF
  2118.                 OTHERWISE
  2119.                     EXIT
  2120.             ENDCASE
  2121.         ENDIF
  2122.     ENDDO
  2123.     RETURN m.wzsautoname
  2124. *: EOP: AUTONAME
  2125.  
  2126. ********************
  2127. procedure PutName
  2128. ********************
  2129. parameters m.wzsFType, m.wzsMethod, m.wzlDelFile
  2130.     private m.wzsSafety, m.wzsFname, m.wzsPrompt, m.wzsString
  2131.  
  2132.     m.wzsMethod=iif(empty(m.wzsMethod),'',m.wzsMethod)
  2133.  
  2134.     m.wzsSafety=set('safety')
  2135.     set safety on
  2136.  
  2137.     do while .t.
  2138.         *- don't supply default of "*.ext" if _mac (4/22/94 jd)
  2139.         IF _mac
  2140.             m.wzsFName=putfile(STRTRAN(C_SAVETO_LOC,"@1",proper(locword(m.wzsFType))), ;
  2141.                 "", FileExt(m.wzsFType,m.wzsMethod))
  2142.         ELSE
  2143.             m.wzsFName=putfile(STRTRAN(C_SAVETO_LOC,"@1",proper(locword(m.wzsFType))), ;
  2144.                 '*.'+FileExt(m.wzsFType,m.wzsMethod), FileExt(m.wzsFType,m.wzsMethod))
  2145.         ENDIF
  2146.         if empty(m.wzsFName)
  2147.             exit && user cancelled putfile()
  2148.         endif
  2149.         if m.wzlDelFile
  2150.             do case
  2151.             case m.wzsFType='CATALOG'
  2152.                 erase (m.wzsFName)
  2153.                 erase (forceext(m.wzsFName,'FCT'))
  2154.             case m.wzsFType='TABLE'
  2155.                 erase (m.wzsFName)
  2156.                 erase (forceext(m.wzsFName,'FPT'))
  2157.                 erase (forceext(m.wzsFName,'CDX'))
  2158.             case m.wzsFType='QUERY'
  2159.                 erase (m.wzsFName)
  2160.             case m.wzsFType='FORM'
  2161.                 erase (m.wzsFName)
  2162.                 erase (forceext(m.wzsFName,'SCT'))
  2163.             case m.wzsFType='REPORT'
  2164.                 erase (m.wzsFName)
  2165.                 erase (forceext(m.wzsFName,'FRT'))
  2166.             case m.wzsFType='LABEL'
  2167.                 erase (m.wzsFName)
  2168.                 erase (forceext(m.wzsFName,'LBT'))
  2169.             case m.wzsFType='PROGRAM'
  2170.                 erase (m.wzsFName)
  2171.             endcase
  2172.             exit
  2173.         endif
  2174.         do case
  2175.         *- I believe this should be FCT, not FCX as was the case (jd 5/6/94)
  2176.         *- also, changed code to "YESNO" code since question is asked (jd 5/12/94)
  2177.         case m.wzsFType='CATALOG' .and. file(forceext(m.wzsFName,'FCT'))
  2178.             IF (MESSAGEBOX(STRTRAN(C_OVERWRITE_LOC,"@1",forceext(m.wzsFName,'FCT')),4) = K_NO)
  2179.                 exit
  2180.             endif
  2181.         case m.wzsFType='TABLE' .and. file(forceext(m.wzsFName,'FPT'))
  2182.             IF (MESSAGEBOX(STRTRAN(C_OVERWRITE_LOC,"@1",forceext(m.wzsFName,'FPT')),4) = K_NO)
  2183.                 exit
  2184.             endif
  2185.         case m.wzsFType='FORM' .and. file(forceext(m.wzsFName,'SCT'))
  2186.             IF (MESSAGEBOX(STRTRAN(C_OVERWRITE_LOC,"@1",forceext(m.wzsFName,'SCT')),4) = K_NO)
  2187.                 exit
  2188.             endif
  2189.         case m.wzsFType='REPORT' .and. file(forceext(m.wzsFName,'FRT'))
  2190.             IF (MESSAGEBOX(STRTRAN(C_OVERWRITE_LOC,"@1",forceext(m.wzsFName,'FRT')),4) = K_NO)
  2191.                 exit
  2192.             endif
  2193.         case m.wzsFType='LABEL' .and. file(forceext(m.wzsFName,'LBT'))
  2194.             IF (MESSAGEBOX(STRTRAN(C_OVERWRITE_LOC,"@1",forceext(m.wzsFName,'LBT')),4) = K_NO)
  2195.                 exit
  2196.             endif
  2197.         otherwise
  2198.             exit
  2199.         endcase
  2200.     enddo
  2201.  
  2202.     set safety &wzsSafety
  2203.     return m.wzsFName
  2204. *- eop PutName
  2205.  
  2206. ********************
  2207. procedure LocWord
  2208. ********************
  2209. * This procedure returns the localized word for the type
  2210. * of file.
  2211. parameters m.wzsType, m.wziVariation
  2212.  
  2213.     m.wzsType=upper(m.wzsType)
  2214.  
  2215.     do case
  2216.     case empty(m.wziVariation)
  2217.         do case
  2218.         case m.wzsType='TABLE'
  2219.             return C_TABLE_LOC        && Table
  2220.         case m.wzsType='QUERY'
  2221.             return C_QUERY_LOC        && Query
  2222.         case m.wzsType='FORM'
  2223.             return C_FORM_LOC        && Screen
  2224.         case m.wzsType='REPORT'
  2225.             return C_REPORT_LOC        && Report
  2226.         case m.wzsType='LABEL'
  2227.             return C_LABEL_LOC        && Label
  2228.         case m.wzsType='PROGRAM'
  2229.             return C_PROGRAM_LOC    && Program
  2230.         case m.wzsType='CATALOG'
  2231.             return C_CATALOG_LOC    && Catalog
  2232.         endcase
  2233.     case m.wziVariation=1 && "your screen", "your report", etc.
  2234.         do case
  2235.         case m.wzsType='TABLE'
  2236.             return C_TABLE1_LOC        && your table
  2237.         case m.wzsType='QUERY'
  2238.             return C_QUERY1_LOC        && your query
  2239.         case m.wzsType='FORM'
  2240.             return C_FORM1_LOC        && your screen
  2241.         case m.wzsType='REPORT'
  2242.             return C_REPORT1_LOC    && your report
  2243.         case m.wzsType='LABEL'
  2244.             return C_LABEL1_LOC        && your label
  2245.         case m.wzsType='PROGRAM'
  2246.             return C_PROGRAM1_LOC    && your program
  2247.         endcase
  2248.     case m.wziVariation=2 && "The new screen", "The new report", etc.
  2249.         do case
  2250.         case m.wzsType='FORM'
  2251.             return C_FORM2_LOC        && The new screen
  2252.         case m.wzsType='REPORT'
  2253.             return C_REPORT2_LOC    && The new report
  2254.         case m.wzsType='LABEL'
  2255.             return C_LABEL2_LOC        && The new label
  2256.         endcase
  2257.     case m.wziVariation=3 && "Screen Wizard", "Report Wizard", etc.
  2258.         do case
  2259.         case m.wzsType='TABLE'
  2260.             return C_TABLE3_LOC        && Table Wizard
  2261.         case m.wzsType='QUERY'
  2262.             return C_QUERY3_LOC        && Query Wizard
  2263.         case m.wzsType='FORM'
  2264.             return C_FORM3_LOC        && Screen Wizard
  2265.         case m.wzsType='REPORT'
  2266.             return C_REPORT3_LOC    && Report Wizard
  2267.         case m.wzsType='LABEL'
  2268.             return C_LABEL3_LOC        && Label Wizard
  2269.         case m.wzsType='PROGRAM'
  2270.             return C_PROGRAM3_LOC    && Application Wizard
  2271.         endcase
  2272.     endcase
  2273. *- eop locword.prg
  2274.  
  2275. *!*****************************************************************************
  2276. *!       Function: FORCEDEC
  2277. *!*****************************************************************************
  2278. FUNCTION ForceDec
  2279. *)
  2280. *) FORECDEC - Force a string to a certain number of decimal places
  2281. PARAMETER cString, nDecimals
  2282.  
  2283. RETURN STR(VAL(cString),LEN(cString) + nDecimals + 1,nDecimals)
  2284.  
  2285. *------------------------------------
  2286. FUNCTION CleanWhite
  2287. *------------------------------------
  2288.     *- strip out leading white space
  2289.     PARAMETER cText
  2290.  
  2291.     LOCAL cTmp
  2292.  
  2293.     cTmp = STRTRAN(TRIM(cText),C_CRLF,C_CR)
  2294.     cTmp = STRTRAN(cTmp,C_TAB,' ')
  2295.     DO WHILE C_CR + ' ' $ cTmp
  2296.         cTmp = STRTRAN(cTmp,C_CR+' ',C_CR)
  2297.     ENDDO
  2298.     DO WHILE LEFT(cTmp,1) $ C_LF + ' '
  2299.         cTmp = SUBS(cTmp,2)
  2300.     ENDDO
  2301.     RETURN cTmp
  2302.  
  2303. ENDFUNC
  2304.  
  2305. FUNCTION CHRTRANC(d1,d2,d3)
  2306. RETURN CHRTRAN(m.d1,m.d2,m.d3)
  2307.  
  2308. *----------------------------------
  2309. FUNCTION GetArray
  2310. *----------------------------------
  2311. PARAMETER cText, aList
  2312. LOCAL m.iTextLen, m.cchar
  2313.  
  2314. m.iTextLen = LEN(m.cText)
  2315. FOR i = 1 TO m.iTextLen
  2316.  
  2317.     m.cchar = SUBS(m.cText,i,1)
  2318.     
  2319.     IF !ISALPHA(m.cchar) AND !ISDIGIT(m.cchar)
  2320.         LOOP
  2321.     ENDIF
  2322.     
  2323.     nextItem = GetItem(SUBS(m.cText,i))
  2324.     IF EMPTY(aList[1])
  2325.         aList[1] = nextItem
  2326.     ELSE
  2327.         DIMENSION aList[ALEN(aList) + 1]
  2328.         aList[ALEN(aList)] = nextItem
  2329.     ENDIF
  2330.     
  2331.     i = i + AT(nextItem,SUBS(cText,i)) + LEN(nextItem) - 1
  2332. NEXT
  2333. RETURN
  2334.  
  2335. *----------------------------------
  2336. FUNCTION GetItem
  2337. *----------------------------------
  2338.     LPARAMETER m.cText
  2339.  
  2340.     #DEFINE     k_quote             ['"] + '['
  2341.     #DEFINE        k_lbracket            '['
  2342.     #DEFINE        k_rbracket            ']'
  2343.     #DEFINE     k_lparen            "("
  2344.     #DEFINE     k_rparen            ")"
  2345.     #DEFINE     k_space             ' '
  2346.     #DEFINE     k_comma             ','
  2347.     #DEFINE     k_tab               CHR(9)
  2348.     #DEFINE     k_semicol            ";"
  2349.     #DEFINE     k_cr                CHR(13)
  2350.  
  2351.     LOCAL m.iLineLoc, m.quote, m.word, m.n1, m.lparenct, m.iTextLen
  2352.  
  2353.     *- get everything up to next unenclosed rparen or rbracket
  2354.     m.iTextLen = LEN(m.cText)
  2355.     FOR m.iLineLoc = 1 TO m.iTextLen
  2356.  
  2357.         m.cchar = SUBS(m.cText,m.iLineLoc,1)
  2358.         
  2359.         IF ISALPHA(m.cchar) OR ISDIGIT(m.cchar)
  2360.             LOOP
  2361.         ENDIF
  2362.  
  2363.         *- treat any sequence of spaces or tabs as 1 word
  2364.         IF m.cchar $ k_space + k_tab + k_cr
  2365.             FOR m.iLineLoc = m.iLineLoc + 1 TO m.iTextLen
  2366.                 m.cchar = SUBS(m.cText,m.iLineLoc,1)
  2367.                 IF !m.cchar $ k_space + k_tab + k_cr
  2368.                     EXIT
  2369.                 ENDIF
  2370.             NEXT
  2371.         ENDIF
  2372.         
  2373.         *- if lparen, move ahead to matching rparen
  2374.         IF m.cchar $ k_lparen + k_lbracket
  2375.             =GetRParen(m.cText,@iLineLoc,m.iTextLen)
  2376.             EXIT
  2377.         ENDIF
  2378.  
  2379.     NEXT
  2380.  
  2381.     RETURN LEFT(m.cText,m.iLineLoc)
  2382.  
  2383. ENDFUNC
  2384.  
  2385. *----------------------------------
  2386. FUNCTION GetRParen
  2387. *----------------------------------
  2388.     LPARAMETERS cText,iLineLoc,m.iTextLen
  2389.     LOCAL cchar, m.rparen, m.lparenct
  2390.     m.cchar = SUBS(cText,iLineLoc,1)
  2391.     m.rparen = IIF(m.cchar = k_lparen, k_rparen, k_rbracket)
  2392.     m.lparenct = 1
  2393.     FOR m.iLineLoc = m.iLineLoc + 1 TO m.iTextLen
  2394.         *- treat enquoted stuff as 1 word
  2395.         m.cchar = SUBS(m.cText,m.iLineLoc,1)
  2396.         IF m.cchar $ k_quote
  2397.             m.endquote = IIF(m.cchar = "[","]",m.cchar)
  2398.             m.iLineLoc = m.iLineLoc + AT(m.endquote, SUBS(m.cText,iLineLoc + 1)) + 1
  2399.             m.cchar = SUBS(m.cText,m.iLineLoc,1)
  2400.         ENDIF
  2401.         IF m.cchar = m.rparen
  2402.             EXIT
  2403.         ENDIF
  2404.         IF m.cchar $ k_lparen + k_lbracket
  2405.             *- found a nested lparen
  2406.             =GetRParen(m.cText, @iLineLoc, m.iTextLen)        && recursive call!
  2407.         ENDIF
  2408.     NEXT
  2409.     RETURN
  2410. ENDFUNC
  2411.  
  2412.  
  2413. *----------------------------------
  2414. FUNCTION pReadOnly
  2415. *----------------------------------
  2416.     LPARAMETER cFile
  2417.  
  2418.     LOCAL ARRAY aDirInfo[1]
  2419.  
  2420.     IF ADIR(aDirInfo,cFile) == 0
  2421.         *- file isn;t there, so fail
  2422.         RETURN .T.
  2423.     ENDIF
  2424.  
  2425.     RETURN ('R' $ aDirInfo[1,5])
  2426.  
  2427. ENDFUNC
  2428.  
  2429. *----------------------------------
  2430. FUNCTION UpdateSCX
  2431. *----------------------------------
  2432.     PARAMETER cFile, lRecurse
  2433.  
  2434.     LOCAL ARRAY aFiles[1,5]
  2435.     LOCAL i, iALen, cTarget
  2436.     
  2437.     cTarget = cFile + IIF(RIGHT(cFile,1) == IIF(_mac,':','\'),"*.*","")
  2438.     iALen = ADIR(aFiles, cTarget, 'D')
  2439.  
  2440.     FOR i = 1 TO iALen
  2441.     
  2442.         IF !(m.lVCX AND JustExt(aFiles[i,1]) == 'VCX') AND ;
  2443.             !(m.lSCX AND JustExt(aFiles[i,1]) == 'SCX') AND ;
  2444.             !('D' $ aFiles[i,5])
  2445.             *- neither an SCX or a VCX, and not a directory
  2446.             LOOP
  2447.         ENDIF
  2448.         
  2449.         DO CASE
  2450.             CASE 'D' $ aFiles[i,5]
  2451.                 IF aFiles[i,1] == "." OR aFiles[i,1] == ".."
  2452.                     LOOP
  2453.                 ENDIF
  2454.                 IF m.lRecurse
  2455.                     *- directory -- recursive call!
  2456.                     UpdateSCX(AddBS(AddBS(cFile) + aFiles[i,1]), lRecurse)
  2457.                 ENDIF
  2458.                 LOOP
  2459.         
  2460.             CASE  'R' $ aFiles[i,5]
  2461.                 *- file is read-only
  2462.                 =MESSAGEBOX(TRIM(aFiles[i,5]) + E_NOCONVERT3_LOC)
  2463.                 
  2464.             CASE  'H' $ aFiles[i,5] OR 'S' $ aFiles[i,5]
  2465.                 *- file is hidden, or a system file
  2466.                 =MESSAGEBOX(TRIM(aFiles[i,5]) + E_NOCONVERT4_LOC)
  2467.                 
  2468.             OTHERWISE
  2469.                 goMaster.aConvParms[4] = AddBS(JustPath(cFile)) + aFiles[i,1]
  2470.                             
  2471.                 =ACOPY(goMaster.aConvParms,aParms)
  2472.                 oConvObject = CREATE(goMaster.scx30ConverterClass, @aParms, .T.)
  2473.  
  2474.                 IF TYPE("oConvObject") # 'O'
  2475.                     *- object was not created
  2476.                     goMaster.lHadError = .T.
  2477.                     gReturnVal = -1
  2478.                     RETURN
  2479.                 ENDIF
  2480.  
  2481.                 IF oConvObject.lHadError
  2482.                     *- error creating converter object: 
  2483.                     *- assume error has already been presented to user
  2484.                     goMaster.lHadError = .T.
  2485.                     RELEASE oConvObject
  2486.                     gReturnVal = -1
  2487.                     RETURN
  2488.                 ENDIF
  2489.  
  2490.                 gReturnVal = oConvObject.Converter()
  2491.  
  2492.                 RELEASE oConvObject
  2493.         ENDCASE
  2494.     NEXT    && going through array of files to convert
  2495.             
  2496. ENDFUNC        && UpdateSCX
  2497.  
  2498.  
  2499. *- eof